外部锁定是指使用文件系统锁定来管理多个进程对 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
一起使用。(默认情况下不这样做,因为在许多设置中,混合使用上述选项很有用。)