外部锁定是指使用文件系统锁定来管理多个进程对 MyISAM
数据库表的争用。当不能假定单个进程(例如 MySQL 服务器)是唯一需要访问表的进程时,就会使用外部锁定。以下是一些示例:
如果您运行多个使用相同数据库目录的服务器(不推荐),则每个服务器都必须启用外部锁定。
如果您使用 myisamchk 对
MyISAM
表执行表维护操作,则必须确保服务器未运行,或者服务器已启用外部锁定,以便在必要时锁定表文件,以便与 myisamchk 协调对表的访问。使用 myisampack 打包MyISAM
表也是如此。如果服务器在启用外部锁定的情况下运行,则可以随时使用 myisamchk 进行读取操作,例如检查表。在这种情况下,如果服务器尝试更新 myisamchk 正在使用的表,则服务器会在继续操作之前等待 myisamchk 完成。
如果您使用 myisamchk 进行写入操作(例如修复或优化表),或者使用 myisampack 打包表,则 必须 始终确保 mysqld 服务器未使用该表。如果您没有停止 mysqld,至少在运行 myisamchk 之前执行 mysqladmin flush-tables。如果服务器和 myisamchk 同时访问表,则表 可能会损坏。
在启用外部锁定的情况下,每个需要访问表的进程在继续访问表之前,都会获取表文件的文件系统锁定。如果无法获取所有必要的锁定,则该进程将被阻止访问该表,直到可以获取锁定为止(在当前持有锁定的进程释放锁定之后)。
外部锁定会影响服务器性能,因为服务器有时必须等待其他进程才能访问表。
如果您运行单个服务器来访问给定数据目录(通常情况如此),并且在服务器运行时没有其他程序(例如 myisamchk)需要修改表,则不需要外部锁定。如果您只使用其他程序读取表,则不需要外部锁定,尽管如果服务器在 myisamchk 读取表时更改了表,myisamchk 可能会报告警告。
如果禁用了外部锁,则在使用 myisamchk 时,您必须在 myisamchk 执行期间停止服务器,或者在运行 myisamchk 之前锁定并刷新表。为了避免此要求,请使用 CHECK TABLE
和 REPAIR TABLE
语句来检查和修复 MyISAM
表。
对于 mysqld,外部锁由 skip_external_locking
系统变量的值控制。启用此变量时,将禁用外部锁,反之亦然。默认情况下,外部锁处于禁用状态。
可以使用 --external-locking
或 --skip-external-locking
选项在服务器启动时控制外部锁的使用。
如果您确实使用外部锁选项来启用从多个 MySQL 进程对 MyISAM
表的更新,请不要在将 delay_key_write
系统变量设置为 ALL
或对任何共享表使用 DELAY_KEY_WRITE=1
表选项的情况下启动服务器。否则,可能会发生索引损坏。
满足此条件的最简单方法是始终将 --external-locking
与 --delay-key-write=OFF
一起使用。(默认情况下不这样做,因为在许多设置中,混合使用上述选项很有用。)