From f027c1217b5b3ac76e742b6ec4ee75ed79ec5871 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 13 May 2022 13:13:45 +0200 Subject: [PATCH] MDEV-28471 mysql_install_db.exe does not work with --innodb-page-size=64K The error message "InnoDB: innodb_page_size=65536 requires innodb_buffer_pool_size >= 20MiB current 10MiB" is the relevant one. The root cause: mysql_install_db bootstraps with --innodb-buffer-pool-size=10M. Small bufferpool is here by design - bootstrap should succeed, even if there is not much RAM available, bootstrap does not need that much memory. For pagesize 64K specifically, Innodb thinks it needs a larger bufferpool, and thus it lets the bootstrap process die (although the expected behavior in this case would be to adjust value, give warning and continue) The workaround: - pass --innodb-buffer-pool-size=20M, which is suitable for all page sizes. - check the same limit in MSI custom action. Also, the patch adds mtr test for 64K page size. --- mysql-test/main/mysql_install_db_win.test | 7 ++++ sql/mysql_install_db.cc | 2 +- win/packaging/ca/CustomAction.cpp | 49 ++++++++++++++--------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/mysql-test/main/mysql_install_db_win.test b/mysql-test/main/mysql_install_db_win.test index ceb7293f611..c400dbf3fb9 100644 --- a/mysql-test/main/mysql_install_db_win.test +++ b/mysql-test/main/mysql_install_db_win.test @@ -42,6 +42,13 @@ remove_file $log; rmdir $ddir; +# MDEV-28471 - mysql_install_db.exe fails with --innodb-page-size=64K +--disable_result_log +exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R --innodb-page-size=64K --verbose +--enable_result_log +rmdir $ddir; + +# Tests with config file let $restart_parameters=; connection default; diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 713c6ac4c3f..1e79e6444ff 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -333,7 +333,7 @@ static char *init_bootstrap_command_line(char *cmdline, size_t size) " %s" " --bootstrap" " --datadir=." - " --loose-innodb-buffer-pool-size=10M" + " --loose-innodb-buffer-pool-size=20M" "\"" , mysqld_path, opt_verbose_bootstrap ? "--console" : ""); return cmdline; diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp index 328e73accb8..dbd0b36745f 100644 --- a/win/packaging/ca/CustomAction.cpp +++ b/win/packaging/ca/CustomAction.cpp @@ -663,6 +663,12 @@ unsigned long long GetMaxBufferSize(unsigned long long totalPhys) } +/* + Magic undocumented number for bufferpool minimum, + allows innodb to start also for all page sizes. +*/ +static constexpr unsigned long long minBufferpoolMB= 20; + /* Checks SERVICENAME, PORT and BUFFERSIZE parameters */ @@ -791,34 +797,37 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) unsigned long long availableMemory= GetMaxBufferSize(memstatus.ullTotalPhys)/ONE_MB; swprintf_s(invalidValueMsg, - L"Invalid buffer pool size. Please use a number between 1 and %llu", - availableMemory); - if(BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15) + L"Invalid buffer pool size. Please use a number between %llu and %llu", + minBufferpoolMB, availableMemory); + if (BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15 || !BufferPoolSize[0]) { ErrorMsg= invalidValueMsg; goto LExit; } - for (DWORD i=0; i < BufferPoolSizeLen && BufferPoolSize[BufferPoolSizeLen]; - i++) - { - if(BufferPoolSize[i]< '0' || BufferPoolSize[i] > '9') - { - ErrorMsg= invalidValueMsg; - goto LExit; - } - } + BufferPoolSize[BufferPoolSizeLen]=0; MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize); - long long sz = _wtoi64(BufferPoolSize); - if(sz <= 0 || sz > (long long)availableMemory) + wchar_t *end; + unsigned long long sz = wcstoull(BufferPoolSize, &end, 10); + if (sz > availableMemory || sz < minBufferpoolMB || *end) { - if(sz > 0) + if (*end == 0) { - swprintf_s(invalidValueMsg, - L"Value for buffer pool size is too large." - L"Only approximately %llu MB is available for allocation." - L"Please use a number between 1 and %llu.", - availableMemory, availableMemory); + if(sz > availableMemory) + { + swprintf_s(invalidValueMsg, + L"Value for buffer pool size is too large." + L"Only approximately %llu MB is available for allocation." + L"Please use a number between %llu and %llu.", + availableMemory, minBufferpoolMB, availableMemory); + } + else if(sz < minBufferpoolMB) + { + swprintf_s(invalidValueMsg, + L"Value for buffer pool size is too small." + L"Please use a number between %llu and %llu.", + minBufferpoolMB, availableMemory); + } } ErrorMsg= invalidValueMsg; goto LExit;