Mysql列表";写下;命令,或者如何确定mysql命令是否涉及写入操作
我希望识别mysql数据库的所有写入命令,并在每次调用mysql写入命令时执行一个函数。这可能类似于过滤(阻止)某些命令或在新线程上发出web请求。到目前为止,我计划使用mysql的常规日志来确定这些写命令是什么,但这不适用于过滤(阻塞)命令 下面是我发现的一些“写入”mysql命令的列表:Mysql列表";写下;命令,或者如何确定mysql命令是否涉及写入操作,mysql,Mysql,我希望识别mysql数据库的所有写入命令,并在每次调用mysql写入命令时执行一个函数。这可能类似于过滤(阻止)某些命令或在新线程上发出web请求。到目前为止,我计划使用mysql的常规日志来确定这些写命令是什么,但这不适用于过滤(阻塞)命令 下面是我发现的一些“写入”mysql命令的列表: 插入 更新 替换 我还有其他需要担心的边缘案例吗?例如,是否有任何东西可以修改select命令,使其以某种方式成为写入操作?下面的写操作最终会作为上述3种操作之一重新执行吗 “set”是对数据库的写入命
- 插入
- 更新
- 替换
“set”是对数据库的写入命令,还是仅针对mysql会话中使用的变量?好吧,在这个问题上,您已经问了很多,那么您可以做什么:
Com_insert
Com_insert_select
Com_replace
Com_replace_select
Com_select
Com_update
您只需检查这些值是否执行了任何此类操作
我在PHP代码中做过类似的过滤。但背景不同;我们使用的是主从复制体系结构。为了将查询定向到相关服务器(将查询读取到从属服务器,将查询写入主服务器),编写了一个自定义函数来标识查询的类型 值得注意的一点是,事务/锁定/解锁操作中的查询始终被视为写查询 此外,对于
Set
,只有Set AUTOCOMMIT
和Set TRANSACTION
是写入命令
请在下面找到我们正在使用的实际代码的大致精简版本:
/*
* All the WRITE operation commands
*/
$write_commands = array(
'create',
'alter',
'drop',
'truncate',
'comment',
'rename',
'insert',
'update',
'delete',
'merge',
'call',
'lock',
'unlock',
'start',
'commit',
'rollback',
'savepoint',
'set',
'replace'
);
/*
* method to determine whether Read or Write
* @param $sql String (SQL query string)
* @return: void
*/
function determineReadOrWrite(string $sql): void {
$dml_query = false;
$words = str_word_count(strtolower(trim($sql)), 1);
$first_word = isset($words[0]) ? $words[0] : '';
$second_word = isset($words[1]) ? $words[1] : '';
if (in_array($first_word, $this->write_commands)) {
/* if it is not "set" then we set to master link */
if ($first_word !== 'set'
|| ($first_word === 'set' && $second_word === 'autocommit')
|| ($first_word === 'set' && $second_word === 'transaction')
) {
$dml_query = true;
/* If we Lock tables or Begin a Transaction, we should run on Write servers only */
/* till we Commit/Rollback or Unlock Tables */
if(($first_word === 'start' && $second_word === 'transaction')
|| $first_word === 'lock'){
/* Set whether the current query is starting a Transaction / Lock etc */
$this->wait_for_commit_rollback = true;
}
/* We are doing Commit/Rollback or Unlock Tables */
if ($first_word === 'commit'
|| $first_word === 'rollback'
|| $first_word === 'unlock') {
$this->wait_for_commit_rollback = false;
}
}
}
/* It's a insert/update/delete/etc query - to be run on Write Db only */
if ($dml_query || $this->wait_for_commit_rollback) {
$this->setActiveConnectionToWrite(true);
} else {
$this->setActiveConnectionToRead();
}
}
是否要在应用程序代码中执行此筛选?是PHP吗?我认为在mysql级别上修改会更容易,但如果不可能,那么在该级别上修改会更好。它是php/laravelOk。我已经编写了一个自定义代码来实现类似的功能,但用于不同的需求—主从负载分布。我很快就会发布一个答案。