技术分享 MySQL 8.0 代理用户使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术分享 MySQL 8.0 代理用户使用相关的知识,希望对你有一定的参考价值。

参考技术A

某天有人问了我一个有关 MySQL PROXY 用户该如何使用的问题。

原问题是这样的:MySQL 版本从 5.5 升级到 8.0 后,proxy 用户怎么无法使用了?我之前是按照你博客上写的方法使用的,但是在升级后,安装插件提示如下错误:

这个咋回事?

我给了一个大家都很讨厌的答案: 去看 MySQL8.0 官方手册吧。

auth_test_plugin.so 是 MySQL 5.5 的插件,仅限于测试环境,不推荐线上使用,仅限功能演示。之后的一系列大版本安装包里都不包含这个插件,所以使用方法有些差异。

我在下面示例中使用插件 mysql_native_password ,这个插件自带 proxy 用户功能,所以需要在配置文件里开启对应的开关,并重启 MySQL 实例:(如果使用 sha256_password , 应该把参数 sha256_password_proxy_users=ON 也加到配置文件里。)

使用 proxy 用户功能之前,需要安装 mysql_no_login 插件,阻止隐藏在 proxy 用户下的真实用户登录 MySQL 。

创建一个 proxy 用户 ytt_fake ,使用认证插件 mysql_native_password :

使用 Proxy 用户登录 MySQL :

确认下变量 proxy_user 的值是不是 ytt_fake :

使用 proxy 用户登录后,查看当前登录用户信息:用户实际上是 ytt_real 。

确认下权限:具有真实用户的所有权限。

用 proxy 用户创建表、插入记录、查询、销毁表:

由于真实用户 ytt_real 使用认证插件 mysql_no_login ,MySQL 不允许此用户登录:

技术分享 | TiDB 对大事务的简单拆分

作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


长期以来,在 MySQL 的开发规范里一般都会这么写: 禁止大事务!话题转到 TiDB ,依然应该是:禁止大事务!

TiDB 由于事务本身分布式特性,加之后台 RAFT 复制导致的写放大,非常不推荐使用大事务。

TiDB 在4.0 之前的版本对事务要求有些过于细致,比如:
  1. 单个事务包含的 SQL 语句不超过5000条
  2. 单条 KV entry 不超过6MB
  3. KV entry 的总条数不超过30w
  4. KV entry 的总大小不超过100MB
上面的几点限制会导致一些 DML 语句写入受阻,比如下面这三类经典无过滤条件语句:
  1. insert ... select ... where 1
  2. update ... where 1
  3. delete from ... where 1
非常容易出现事务过大的错误: ERROR 8004 (HY000): transaction too large, len:300001。 一般有如下方法来规避这个问题:
  1. 针对Insert、delete 语句开启无安全保证的dml batch 特性:TiDB_batch_insert、TiDB_batch_delete。
  2. 分块拆分整条update 语句。

在4.0 之后的版本里,除了单个kv entry 大小依然限制为最大6MB,其他几个限制全部被取消。

只需要在配置文件里加上如下选项就可涵盖大部分事务:

performance.txn-total-size-limit: 10737418240(范围 1G 到10G)

那是不是4.0 版本后就可以随意写事务了? 当然不是! 由于TiDB 的写放大,也会连带导致内存占用成倍增长,对其他业务会有很大影响,所以TiDB对最大事务支持硬性限制其为10G。比如用DM 来同步MySQL数据到TiDB,大事务会导致内存加大,写入延迟剧增,进而影响其他的写性能。

所以还是得禁止大事务,拆分为小事务批量处理。

那如何对大事务进行拆分呢? 单从业务方面讲,业务类型不同,对应的拆分方法不同,可能一本书都写不完。 这里我仅仅从数据库角度,细分为从表角度,再进一步到DML语句角度如何拆分。

上面列的这三条经典语句看起来很简单,但是没有过滤条件,如果表索引数非常多,即使表记录数不大,也会是一个大事务,只不过这个事务只包含一条DML语句。但是这类语句的拆分实际上要看表结构怎么定义,分为三种:

  1. 有主键,并且主键连续
  2. 有主键,主键不连续
  3. 表无主键(类似第一种)
第一种最容易拆分,根据主键来划分不同的块即可。

举个例子:

表t1 有100W 条记录,除主键外有6个索引,对表t1 进行update :

update ytt.t1 set log_date = current_date() - interval ceil(rand()*1000) day where 1;

在默认自动提交下,这条语句其实就是隐式大事务语句,在内部转换为 :

begin

update ytt.t1 set log_date = current_date() - interval ceil(rand()*1000) day where 1;

commit;

假设表t1主键为自增且连续,那很简单,把这个事务分为10个小事务,每次更新10W条记录,而不是一次性更新100W条。脚本大致如下:

root@ytt-ubuntu:~/scripts# cat update_table_batch
#!/bin/sh
# TiDB 拆分更新
for i in `seq 1 10`;do
    min_id=$(((i-1)*100000+1))
    max_id=$((i*100000))
    queries="update t1 set log_date = date_sub(current_date(), interval ceil(rand()*1000) day)  \\
        where id >=$min_id and id<=$max_id;" 

    mysql --login-path=TiDB_login -D ytt -e "$queries" &
done
第二种,针对不连续的自增主键场景。

第一种最为常见,在 TiDB 里强烈不推荐使用连续自增字段来做主键,这会导致潜在的单 region 写热点问题。所以自增主键推荐使用 auto_random 特性来随机写入,避免连续性。

上面脚本里列出的方法就变得不太适合。那该怎么拆呢? 可以稍加变通,用窗口函数 row_number() 来补模拟主键,更新表改为 t2 ,改写后的脚本大致如下:

root@ytt-ubuntu:~/scripts# cat update_table_batch
#!/bin/sh
# TiDB 拆分更新
for i in `seq 1 10`;do
    min_id=$(((i-1)*100000+1))
    max_id=$((i*100000))
    queries="update t2 a, (select *,row_number() over(order by id) rn from t2) b set a.log_date =  \\
        date_sub(current_date(), interval ceil(rand()*1000) day)  \\
        where a.id = b.id and (b.rn>=$min_id and b.rn<=$max_id);"
    mysql --login-path=TiDB_login -D ytt -e "$queries" &
done

其实以上两种思路已经包含了绝大多数拆分场景。 MySQL 或者 TiDB 对于没有主键的表都默认包含一个隐式自增 ID 来区分行之间关系,所以为了避免在DML层来增加复杂的拆分策略,依然强烈建议使用显式主键!

结语

虽然 TiDB 4.0 版本后,对大事务支持已经非常好,但这不是可以随便用大事务的理由,还是要做好表设计提前拆、检索表数据提前拆等拆分策略,才能更好的让数据库服务好业务。

以上是关于技术分享 MySQL 8.0 代理用户使用的主要内容,如果未能解决你的问题,请参考以下文章

第十三期分享:MYSQL8.0新特性

技术分享 | MySQL 表空间碎片整理方法

技术分享 | 在长字符串上创建索引

自动驾驶技术平台分享:百度Apollo开放平台8.0再升级,更简单,更便捷,更高效

技术分享 MySQL 启动失败的常见原因

MySQL 8.0 MVCC 源码解析