Bug #24052 On Win64, MEMORY tables are limited to 4 GB
Submitted: 7 Nov 2006 17:25 Modified: 18 Dec 2006 18:56
Reporter: John David Duncan Email Updates:
Status: Closed Impact on me:
Category:MySQL Server: Memory storage engine Severity:S1 (Critical)
Version:5.0.27/4.1:/5.1 OS:Windows (Windows 64)
Assigned to: Michael Widenius CPU Architecture:Any
Tags: backport_050030SP1, bfsm_2006_12_07

[7 Nov 2006 17:25] John David Duncan
MySQL's memory tables are limited by the system variable max_heap_table_size.  This variable (and many other values that follow from it) are of type "ulong"

On 64-bit Windows, "ulong" is an unsigned 32-bit type.  Therefore, even on 64-bit Windows, MEMORY tables cannot be larger than 4 GB.

(However, on 64-bit Solaris, and maybe some other 64-bit platforms, you can currently have MEMORY tables that are larger than 4 GB.   This is possible because the "-m64"  switch in gcc makes "long" a 64-bit type.)

How to repeat:
Start the server with max_heap_table_size = 15000000000 

Then "SHOW VARIABLES LIKE max_heap_table_size"

If the reported value is the same as you set it to (instead of just 4 GB )  then it should work.

Suggested fix:
*** mysql-5.0.27-dist/include/my_global.h       Fri Oct 20 17:22:53 2006
--- mysql-5.0.27/include/my_global.h    Tue Nov  7 08:39:52 2006
*** 821,824 ****
--- 821,827 ----

+ #ifdef _WIN64
+ typedef unsigned long long ulong;  /* ulong should be a 64-bit type on 64-bit platforms */
+ #else
   #if !defined(HAVE_ULONG) && !defined(TARGET_OS_LINUX) && !defined  (__USE_MISC)
   typedef unsigned long ulong;            /* Short for unsigned long */
[7 Nov 2006 17:34] MySQL Verification Team
Thank you for the bug report.
[7 Nov 2006 18:58] John David Duncan
The fix I proposed will not work, according to this note I got from Igor Chernyshev:
Hi JD,

I tried to change ulong myself, but that creates a true mess... MYSQL uses "unsigned long" and "ulong" interchangeably for defining the same functions or data. I can change "ulong", but cannot change "unsigned long". So I had to fix a bunch of header files from "unsigned long" to "ulong". However, even after that it was not stable - mysqladmin would crash, etc... I figured out that there are multiple places where we dereference pointers and compiler would not check that, or the places where we rely on SIZEOF_LONG definition. I also suspect that some of the printf formatting would break because it sees a wrong data size.

Now that there was such a mess I did a simpler thing - I changed max_heap_table_size and tmp_table_size to be ulonglong, and changed all other "heap" structures along with that. It seems to work correctly. We should just remember that the table size includes both data and index structures.

[7 Nov 2006 19:07] MySQL Verification Team
This fix will not work, because what is required is to check how did __int64 failed to be configured for ulong, long, ulonglong and longlong.
[18 Dec 2006 18:56] Paul DuBois
Noted in 5.0.32, 5.1.14 changelogs.

The size of MEMORY tables and internal temporary tables was limited
to 4GB on 64-bit Windows systems.