Bug #41124 Server hangs on Windows with --external-locking after INSERT...SELECT
Submitted: 29 Nov 2008 14:28 Modified: 27 Mar 2009 23:22
Reporter: Ingo Struewing Email Updates:
Status: Closed
Category:Server: Locking Severity:S3 (Non-critical)
Version:5.0, 5.1, 6.0 OS:Microsoft Windows
Assigned to: Ingo Struewing Target Version:
Triage: Triaged: D2 (Serious)

[29 Nov 2008 14:28] Ingo Struewing
Description:
This has been detected during analyze of Bug#38133 (Myisamlog test fails on Windows). The
third patch (http://lists.mysql.com/commits/58606) contains a possible fix for the
problem, but it was rejected for Bug#38133. For more information, you may study the
review thread attached at that link.

IMHO the problem is that my_lock() behaves differently on Windows than on UNIX-like
platforms. On Windows, a lock on a file does not necessarily replace a former lock by the
same process. Namely it is possible to hold an exclusive lock (write lock) in parallel to
a shared lock (read lock). On UNIX-like platforms a new lock on the same portion of a
file replaces a former lock on the same portion of the file.

MyISAM code, in mi_lock_database(), clearly expects the behavior of UNIX-like platforms.
When it changes the lock type on the file, say from write lock to read lock, it just
requests a read lock on the file, expecting that the write lock is replaced and goes
away.

How to repeat:
You need a -master.opt file with --external-locking.

CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
# This takes a write lock through the first instance of the table and a
# read lock through the second instance. The write lock is propagated
# to my_lock(), but the read lock is skipped, because a stonger lock
# exists. On unlock, the write lock is removed first. On file level, the
# write lock is converted to a read lock, as the second instance is not
# unlocked yet. On Windows, this conversion turns into an additional
# lock, because a write lock and a read lock can co-exist on a file.
# Unlocking the second instance leads to the latest lock to be removed
# from the file. But the former lock, the write lock, still exists on
# Windows.
INSERT INTO t1 SELECT * FROM t1;
# This blocks on Windows, because it tries a write lock on the file,
# that is write locked already. It blocks, even though it's the same
# process taking the lock.
INSERT INTO t1 VALUES (2);

Suggested fix:
I suggest to stick with the valuable tradition of mysys to compensate differences of
platforms. This could be done in my_lock() by removing an old lock with (void)
UnlockFileEx() before taking a new one with LockFileEx(). See the link to my proposed
patch for Bug#38133.

Perhaps Windows has a flag or a different set of functions to accomplish the same. After
all, unlocking before (re-)locking could leave a short time frame with an unlocked file
when the lock type changes, which could be a problem for co-working processes. But if
there is no other way to solve it with Windows features, it is better to live with the
race condition than to block after INSERT...SELECT.

Please note: If you fix the bug in my_lock(), or otherwise in mi_lock_database(), you may
remove the code from mi_examine_log(), which tries to accomplish the same on the client
side only. See later patches for Bug#38133.
[29 Nov 2008 14:34] Ingo Struewing
Suggested triage values:
Defect class serious. It can hang the server.
Workaround unacceptable. If user needs --external-locking, he must avoid INSERT...SELECT
and similar statements that do read and write on the same table.
Impact negligible. Who will ever want to use --external-locking on Windows?
[11 Jan 2009 18:32] Ingo Struewing
The fix has now been accepted for Bug#38133 after all.
[22 Feb 2009 19:05] Ingo Struewing
Queued to mysql-6.0-backup.
[27 Mar 2009 16:02] Ingo Struewing
The patch for this is included in the patch for Bug#38133 (Myisamlog test fails on
Windows).

Pushed into 6.0.11-alpha (revid:alik@sun.com-20090326121822-pt84kzxxayzho4mn) (version
source revid:rafal.somla@sun.com-20090302164601-znhm4tadplfi2iqu) (merge vers:
6.0.11-alpha) (pib:6)

For the 6.0.11 changelog: Locking of myisam.log did not work correctly on Windows.
[27 Mar 2009 23:22] Paul DuBois
Noted in 6.0.11 changelog.