Bug #86370 crash on startup, divide by zero, with inappropriate buffer pool configuration
Submitted: 18 May 2017 12:53 Modified: 10 Apr 2018 18:07
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.7.18 OS:Windows
Assigned to: CPU Architecture:Any

[18 May 2017 12:53] Shane Bester
Description:
Affects windows debug/release builds of 5.7, 8.0

5.7.18 release build:

12:29:13 UTC - mysqld got exception 0xc0000094 ;
This could be because you hit a bug. It is also possible that this binary

mysqld.exe!innobase_start_or_create_for_mysql()[srv0start.cc:1707]
mysqld.exe!innobase_init()[ha_innodb.cc:4048]
mysqld.exe!ha_initialize_handlerton()[handler.cc:838]
mysqld.exe!plugin_initialize()[sql_plugin.cc:1200]
mysqld.exe!plugin_init()[sql_plugin.cc:1539]
mysqld.exe!init_server_components()[mysqld.cc:4036]
mysqld.exe!win_main()[mysqld.cc:4673]
mysqld.exe!mysql_service()[mysqld.cc:5125]
mysqld.exe!mysqld_main()[mysqld.cc:5323]
mysqld.exe!__tmainCRTStartup()[crtexe.c:626]

On trunk the crash is here by % since "m" is zero.

buf_pool_size_align(
	ulint	size)
{
	const ulint	m = srv_buf_pool_instances * srv_buf_pool_chunk_unit;
	size = ut_max(size, srv_buf_pool_min_size);

	if (size % m == 0) {
		return(size);
	} else {
		return((size / m + 1) * m);
	}
}

How to repeat:
mysqld --innodb-buffer-pool-size=10G --innodb-buffer-pool-instances=64 --console

Suggested fix:
never divide or modulus by zero.  try auto-correct values or exit gracefully.
[8 Jan 2018 7:41] MySQL Verification Team
Happens with this too:

mysqld --innodb-buffer-pool-size=64G --innodb-buffer-pool-instances=64
[11 Jan 2018 6:30] MySQL Verification Team
I think this solves it:

E:\git\mysql-5.7>git diff
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index b9724ce..c0e53be 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -1377,7 +1377,7 @@ ulint
 buf_pool_size_align(
        ulint   size)
 {
-       const ulint     m = srv_buf_pool_instances * srv_buf_pool_chunk_unit;
+       const ulonglong m = (ulonglong)srv_buf_pool_instances * (ulonglong)srv_buf_pool_chunk_unit;
        size = ut_max(size, srv_buf_pool_min_size);

        if (size % m == 0) {
[11 Jan 2018 6:37] MySQL Verification Team
workaround is you have to make sure that the product of innodb_buffer_pool_chunk_size and innodb_buffer_pool_instances is less than 4294967296
[10 Apr 2018 18:07] Daniel Price
Posted by developer:
 
Fixed as of the upcoming 5.7.23, 8.0.12 release, and here's the changelog entry:

On a Windows 64-bit system, invalid buffer pool configuration values
caused the server to exit on startup.