Bug #118355 Temporary file write failure when creating an index
Submitted: 4 Jun 7:41 Modified: 10 Jun 13:57
Reporter: zhou Dean Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB Plugin storage engine Severity:S3 (Non-critical)
Version:8.0.42 OS:Any
Assigned to: CPU Architecture:Any

[4 Jun 7:41] zhou Dean
Description:
We created an index on a disk with a sector size of 4096 bytes but got an error of Temporary file write failure and found that io buffer memory address is not aligned with IO_BLOCK_SIZE(4k), so direct io pwrite and pread operations will fail. The following is the related bug code:

diff --git a/storage/innobase/ddl/ddl0builder.cc b/storage/innobase/ddl/ddl0builder.cc
index af9fd0c32f5..779ece73753 100644
--- a/storage/innobase/ddl/ddl0builder.cc
+++ b/storage/innobase/ddl/ddl0builder.cc
@@ -673,7 +673,7 @@ dberr_t Builder::init(Cursor &cursor, size_t n_threads) noexcept {

     thread_ctx->m_aligned_buffer =
         ut::make_unique_aligned<byte[]>(ut::make_psi_memory_key(mem_key_ddl),
-                                        UNIV_SECTOR_SIZE, buffer_size.second);
+                                        IO_BLOCK_SIZE, buffer_size.second);

     if (!thread_ctx->m_aligned_buffer) {
       return DB_OUT_OF_MEMORY;
diff --git a/storage/innobase/ddl/ddl0file-reader.cc b/storage/innobase/ddl/ddl0file-reader.cc
index 3581b1c8868..c8a94bd66ae 100644
--- a/storage/innobase/ddl/ddl0file-reader.cc
+++ b/storage/innobase/ddl/ddl0file-reader.cc
@@ -47,7 +47,7 @@ dberr_t File_reader::prepare() noexcept {
   }

   m_aligned_buffer = ut::make_unique_aligned<byte[]>(
-      ut::make_psi_memory_key(mem_key_ddl), UNIV_SECTOR_SIZE, m_buffer_size);
+      ut::make_psi_memory_key(mem_key_ddl), IO_BLOCK_SIZE, m_buffer_size);

   if (!m_aligned_buffer) {
     return DB_OUT_OF_MEMORY;

How to repeat:
1.  The tmpdir must be on a disk with a sector size of 4096 bytes.
2.  Execute the following SQL:

mysql>  create table t1(id int, name varchar(128));
Query OK, 0 rows affected (0.82 sec)

mysql>  insert into t1 values(1, repeat('a', 32));
Query OK, 1 row affected (0.00 sec)

mysql> alter table t1 add index name_idx(name);
ERROR 1878 (HY000): Temporary file write failure.

Suggested fix:
When allocating memory, use IO_BLOCK_SIZE as the alignment size. We set the global innodb_disable_sort_file_cache = 0 to avoid direct IO operations, which can also bypass this problem.
[10 Jun 13:57] MySQL Verification Team
Hello zhou Dean,

Thank you for the report and test case.

regards,
Umesh