gpt4 book ai didi

mysql - mysql "Write"命令列表,或者说如何判断mysql命令是否涉及写操作

转载 作者:行者123 更新时间:2023-11-29 06:38:26 24 4
gpt4 key购买 nike

我希望识别对 mysql 数据库的所有写入命令,并在每次调用 mysql 写入命令时执行一个函数。这可能类似于过滤(阻止)某些命令或在新线程上发出 Web 请求。目前,我打算使用mysql的通用日志来确定这些写入命令是什么,但这不适用于过滤(阻止)命令。

这是我发现的一些“写入”mysql 命令的列表:

  • 插入
  • 更新
  • 替换

还有其他我需要担心的边缘情况吗?例如,是否有任何东西可以修改选择命令以使其成为写入操作?下面的写操作最终会像上述 3 个操作之一一样重新执行吗?

“set”是对数据库的写入命令,还是仅适用于 mysql session 中使用的变量?

最佳答案

我在 PHP 代码中做了类似的过滤。但背景不同;我们使用主从复制架构。为了将查询定向到相关服务器(读取查询到从属服务器,将查询写入到主服务器),编写了一个自定义函数来识别查询的类型

值得注意的一点是,事务/锁定/解锁操作中的查询始终被视为写入查询。

此外,对于Set,只有SET AUTOCOMMITSET 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();
}

}

关于mysql - mysql "Write"命令列表,或者说如何判断mysql命令是否涉及写操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52771160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com