社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

mysql“write”命令列表,或者如何确定mysql命令是否涉及写操作

nick carraway • 5 年前 • 1403 次点击  

我正在查找所有对MySQL数据库的写命令,并在每次调用MySQL写命令时执行一个函数。这可能类似于过滤(阻塞)某些命令或在新线程上发出Web请求。到目前为止,我计划使用MySQL的常规日志来确定这些写命令是什么,但这不适用于过滤(阻塞)命令。

以下是我找到的一些“write”mysql命令的列表:

  • 插入
  • 更新
  • 代替

我还有其他需要担心的边缘问题吗?例如,是否有什么可以修改select命令以使其以某种方式成为写操作?以下写入操作最终会作为上述3种操作之一重新执行吗?

“set”是对数据库的写命令,还是只对MySQL会话中使用的变量?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38194
 
1403 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Madhur Bhaiya
Reply   •   1 楼
Madhur Bhaiya    6 年前

我在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();
    }

}
Anton
Reply   •   2 楼
Anton    6 年前

嗯,你在这个问题上问了很多问题,所以你能做什么:

  1. 如果您想要mysql执行的操作的全局计数器,那么

    显示状态

将返回服务器的所有计数器,包括用于以下操作的计数器

Com_insert 
Com_insert_select 
Com_replace
Com_replace_select
Com_select 
Com_update

您只需检查这些值是否执行了任何此类操作

  1. 监视插入、更新、替换等的另一种方法是使用触发器( https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html )文档中的示例清楚地显示了触发器在哪里做得最好——作为增加局部计数器(变量)的方法。但您仍然应该记住触发器是特定于当前操作/表的。

  2. 说到边缘案例。是的,例如交易和程序。程序可以包括上面的许多操作。所以你需要检查一下。

  3. 一般来说,从数据库外部监视诸如insert这样的原子操作并不是最好的主意。您应该依赖于db means on that(触发器、变量、全局计数器)