8.11.5 外部锁定

外部锁定是使用文件系统锁定来 Management 多个进程对MyISAM数据库 table 的争用。在无法将单个进程(例如 MySQL 服务器)假定为唯一需要访问 table 的进程的情况下,可以使用外部锁定。这里有些例子:

  • 如果运行使用相同数据库目录的多个服务器(不建议),则每个服务器必须启用了外部锁定。

  • 如果使用myisamchkMyISAMtable 执行 table 维护操作,则必须确保服务器未在运行,或者服务器启用了外部锁定,以便根据需要锁定 table 文件以与myisamchk协作以访问 table。使用myisampack打包MyISAMtable 也是如此。

如果服务器在启用了外部锁定的情况下运行,则可以随时使用myisamchk进行诸如检查 table 之类的读取操作。在这种情况下,如果服务器尝试更新myisamchk正在使用的 table,则服务器将 awaitmyisamchk完成后再 continue。

如果使用myisamchk进行修复或优化 table 之类的写操作,或者如果使用myisampack打包 table,则必须始终确保mysqld服务器未使用该 table。如果不停止mysqld,则至少应先运行mysqladmin flush-tables,然后再运行myisamchk。如果服务器和myisamchk同时访问 table,则 table可能已损坏*。

启用外部锁定后,每个需要访问 table 的进程都将在 continue 访问 table 之前获取 table 文件的文件系统锁。如果无法获取所有必需的锁,则会阻止该进程访问 table,直到获得锁为止(在当前持有锁的进程释放它们之后)。

外部锁定会影响服务器性能,因为服务器有时必须 await 其他进程才能访问 table。

如果您运行单个服务器来访问给定的数据目录(通常是这种情况),并且在服务器运行时不需要其他程序(例如myisamchk)来修改 table,则不需要外部锁定。如果仅通过其他程序“读取”table,则不需要外部锁定,尽管如果myisamchk正在读取 table 时服务器更改了 table,则myisamchk可能会报告警告。

在禁用外部锁定的情况下,要使用myisamchk,您必须在myisamchk执行时停止服务器,或者在运行myisamchk之前锁定并刷新 table。 (请参阅第 8.12.1 节“系统因素”。)为避免此要求,请使用CHECK TABLEREPAIR TABLE语句检查和修复MyISAMtable。

对于mysqld,外部锁定由skip_external_locking系统变量的值控制。启用此变量后,将禁用外部锁定,反之亦然。默认情况下,外部锁定是禁用的。

可以使用--external-locking--skip-external-locking选项在服务器启动时控制外部锁定的使用。

如果确实使用外部锁定选项来启用许多 MySQL 进程对MyISAMtable 的更新,则必须确保满足以下条件:

  • 不要将查询高速缓存用于使用由另一个进程更新的 table 的查询。

  • 不要将delay_key_write系统变量设置为ALL来启动服务器,也不要对任何共享 table 使用DELAY_KEY_WRITE=1 table 选项。否则,可能会发生索引损坏。

满足这些条件的最简单方法是始终将--external-locking--delay-key-write=OFF--query-cache-size=0一起使用。 (默认情况下不会进行此操作,因为在许多设置中,混合使用上述选项会很有用.)