爱分享 - 数据库
type: channel
link: http://gxxblw.com/category/数据库
items: Redis 技术在业务场景中的应用与常见面试要点解析
items: MySQL索引详解，面试工作常遇知识点
items: MyBatis+Oracle|的like用法
items: Mysql数据表生成文档表结构，导出并生成word文档的方法
items: linux 定时任务备份至七牛
items: 【MySql】Specified key was too long; max key length is 767 bytes的解决方案
items: Mysql数据库误删/错删数据恢复-binlog日志使用
items: 关于MYSQL中BINLOG_FORMAT的三种模式
items: Mysql中definer引起的视图查询提示密码错误
items: mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8mb4'如何解决？

Redis 技术在业务场景中的应用与常见面试要点解析
type: item
date: 2024-08-05T15:06:00+08:00
description: 文章主要围绕 Redis 展开，首先介绍了 Redis 在业务中的使用场景，如缓存、会话管理、消息队列等。接着详细阐述了 Redis 常见的面试问题，包括数据类型、缓存击穿/穿透/雪崩的定义及应对方法、布隆过滤器的概念及注意事项、数据双写一致性的保证方式、持久化方式（RDB 和 AOF）、缓存删除策略、分布式锁的实现、集群方式（主从复制、哨兵模式、Cluster 集群）以及 Redis 虽是单线程却速度快的原因等，为读者全面了解 Redis 提供了丰富的知识和参考（一）Redis的业务使用场景Redis 是一个开源的内存数据结构存储系统，具有高性能、丰富的数据结构和多种特性，在业务中经常做为中间来进行使用，场景中常见应用场景如下：缓存：对于一些频繁访问且相对静态的数据，比如电商网站中的商品基本信息、用户配置信息等，将其存储在 Redis 中。当应用程序需要获取这些数据时，首先从 Redis 中查询，如果 Redis 中不存在，再从数据库中查询并将结果存入 Redis，下次访问时就可以直接从 Redis 中获取，大大减少数据库的访问压力，提高响应速度会话管理：传统的 Web 应用中，会话信息通常存储在服务器的内存中或者使用 Cookie /Session存储。然而，当多服务器集群部署时，使用服务器内存存储会话会面临会话同步的问题，Redis 可以作为一个集中式的会话存储解决方案，将用户的会话信息存储在 Redis 中，便于多台服务器共享数据，避免重复登录或登录失效等问题消息队列: Redis 的列表数据结构可以用作简单的消息队列。生产者将任务或者消息以 LPUSH 命令推入 Redis 列表的一端，消费者使用 RPOP 或者 BRPOP 命令从列表的另一端取出任务或消息进行处理,在Java来说Redision第三方库直接可使用的队列类型进行使用发布/订阅模式：Redis 提供了发布/订阅功能，发布者将消息发布到特定的频道，订阅了该频道的所有客户端都可以收到消息。这种模式适用于实时性要求较高、一对多的消息通知场景，比如构建聊天室或者集群中广播接收可用该特性实现业务功能分布式锁：在分布式系统中，多个进程或线程可能需要访问共享资源，为了保证资源的互斥访问，可以使用 Redis 实现分布式锁。通过 SETNX 命令设置一个键值对，如果键不存在则设置成功并获取锁，处理完业务后通过 DEL 命令释放锁。限速器实现：利用 Redis 的过期时间和计数功能可以实现限速功能。例如，限制用户在一定时间内的请求次数，防止恶意请求或滥用。可以通过记录用户的请求时间戳或请求次数，并结合 Redis 的过期设置来控制访问频率排行榜: 如玩家得分排行榜、等级排行榜等可以使用 Redis 的有序集合来实现。玩家的游戏数据（如得分、等级等）作为有序集合的元素分值，玩家 ID 作为元素。通过 Redis 的 ZADD、ZRANK 等命令可以方便地添加玩家数据到排行榜、查询玩家的排名等操作。地理位置服务:Redis 从 3.2 版本开始支持地理位置相关的操作。在社交应用、外卖应用、打车应用等场景中，可以使用 Redis 存储用户或地点的地理位置信息，并通过相关命令查询附近的用户或地点。同时我们还可以利用 Redis 的地理位置功能可以实现地理围栏的应用。例如，在物流配送系统中，可以设置地理围栏区域，当配送车辆进入或离开某个区域时，触发相应的事件和操作（二）Redis常见面试问题1. Redis常见的数据类型有哪些？答： 字符串类型（string）,哈希（hash）,列表（list）,集合（set）,有序集合（sorted set）2. 什么是缓存击穿/穿透/雪崩是指什么，如何应对处理？答：缓存击穿：缓存击穿是指一个 key 非常热点，在不停的扛着大并发，大并发集中对这一个点进行访问，当这个 key 突然失效的瞬间，持续的大并发就穿破缓存，直接请求查询数据库，就像在一道坚固的屏障上击破了一个洞，处理方式有如下几个方式互斥锁：当发现缓存失效时，不是立即去访问数据库，而是先通过互斥锁（如 Java 中的 synchronized 或 ReentrantLock）控制只有一个线程去访问数据库，其他线程等待。获取数据后更新缓存，然后释放锁，其他等待的线程直接从缓存中获取数据，设置热点数据永不过期：对于一些特别热点且更新不频繁的数据，可以考虑不设置过期时间，这样就不会出现因为过期而导致的缓存击穿问题。但这种方法需要注意数据的更新操作，当数据更新时，需要同时更新缓存和数据库以保持一致性。缓存穿透：缓存穿透是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是，数据先查询缓存，缓存没有的话再去查询数据库，数据库没有的话就返回空结果。但当用户故意去查询一个数据库中不存在的数据时…

MySQL索引详解，面试工作常遇知识点
type: item
date: 2024-07-31T21:02:00+08:00
description: 一、什么是索引先说结论，mysql索引就是通过数据结构或存储结构(B+树)，从而提高查找的效率，举个例子，MySQL索引就像书的目录。想象一下我们小学使用的新华字典，当你想在一本厚厚字典中查询某个字的相关内容时，如果没有目录，你可能需要从头到尾一页一页地翻，非常耗时。而有了目录，你只需查看目录，然后直接跳到相关的页面，速度快了很多，在这个例子中，mysql表的数据，就好比新华字典里的字，而索引则对应字典的目录二、 索引有什么用（1）提高查询效率从新华字典的例子中，我们知道索引能显著加快数据的查找速度，当你在一个有数百万行数据的表中搜索某个特定值时，有了索引，MySQL可以快速定位到相关数据，而不需要扫描逐行扫描（2）排序数据有了索引可以帮助我们对某个数据按某个顺序排序，进一步提高查询效率，比如新华字典按拼音字母的顺序编排方式（2）唯一性约束可以创建唯一索引来确保某列的值是唯一的，这有助于保证数据的完整性和一致性。例如在用户登录账号通常应该是唯一的，可以在该列上创建唯一索引。三、索引分类与使用我们先新建一张数据表,在后面使用CREATE TABLE `t_order` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_no` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '订单编号', `good_name` varchar(125) COLLATE utf8_bin DEFAULT NULL COMMENT '商品名称', `good_content` varchar(125) COLLATE utf8_bin DEFAULT NULL COMMENT '商品介绍', `user_id` int(11) DEFAULT NULL COMMENT '用户ID', `order_price` decimal(10,2) DEFAULT NULL COMMENT '订单金额', `status` tinyint(2) DEFAULT NULL COMMENT '订单状态：0待支付，1已支付，2已取消', `create_time` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='订单表';1. 索引分类根据索引列数和数据结构等进行分类，索引的分类大致如下（1）按索引列个数分类单一(单列表)索引：基于单个列创建的索引。复合(联合)索引：基于多个列创建的索引。使用技巧： 如果查询通常基于单个列进行，且该列的选择性较高（即该列不同值的数量较多），那么单一索引可能是更好的选择。例如，在一个订单表中，如果经常根据订单号（order_no）来查询订单详情，为 order_no 列创建单一索引是合适的。然而，如果查询经常涉及多个列的组合条件，那么复合索引可能更有优势。比如，在一个员工表中，经常根据员工的部门（department）和职位（position）来查询员工信息，创建一个基于 department 和 position 的复合索引会更高效。但需要注意的是，复合索引的列顺序很重要。通常，将选择性更高（不同值更多）的列放在前面（最左前缀原则）另外，过多的索引会增加数据插入、更新和删除操作的开销，并且会占用更多的存储空间，基于这方面考虑更多考虑复合索引在决定使用单一索引还是复合索引时，需要综合考虑查询模式、数据分布、表的更新频率等因素进行权衡和选择。 创建索引# 单一索引,默认为Btree，B+树结构 ALTER TABLE t_order ADD INDEX idx_order_no (order_no); #复合索引，使用user_id和status建立联合索引 ALTER TABLE t_order ADD INDEX idx_user_id_status (user_id, status);（2）按索引数据结构分类B 树索引(B-Tree)：包括 B+树索引，是 MySQL 中常见的索引结构，适用于范围查询和排序操作。哈希索引(Hash)：通过哈希函数计算索引值的位置，适用于精确匹配查询，但不支持范围查询。使用技巧：hash索引对于精确匹配的查询效率比较高，可以快速定位数据，单hash索引不支持范围查询如大于、小于、介于，like 等范围索引查询操作，也不支持列索引排序，同时如果索引列重复值较多，会有hash冲突，同时它也不适用于频繁更新的列，需要重新计算hash维护成本低，例如t_order表中，可以考虑使用hash结构的索引B-Tree结构索引支持范围查询，同时也支持排序操…

MyBatis+Oracle|的like用法
type: item
date: 2023-01-04T15:47:00+08:00
description: 在xml中我们可以这样拼接like关键词MyBatis+Oracle的like用法field_name like CONCAT(CONCAT('%',#{field_name}),'%')MyBatis+MySQL的like用法field_name like concat('%',#{field_name},'%')

Mysql数据表生成文档表结构，导出并生成word文档的方法
type: item
date: 2022-12-30T08:45:00+08:00
description: 因为项目需要编写库表结构word文档，需要交付验收，下面给大家介绍一种我用的方式步骤一：使用sql生成表结构数据SELECT ORDINAL_POSITION 序号, COLUMN_NAME 列名, COLUMN_TYPE 数据类型, -- COLUMN_DEFAULT 默认值, (CASE IS_NULLABLE WHEN 'NO' THEN '否' WHEN 'YES' THEN '是' ELSE '' END) 允许为空, COLUMN_KEY 主键, COLUMN_COMMENT 注释 FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA='dbname' -- 库名 AND table_name='table_demo' -- 表明步骤二：使用Navicat Premium工具导出Excle我们将查询成功的数据导出Excel，并将内容复制到doc中即可有其它更好方式的可以推荐下哦，虽然这个方法步骤有点多，但是总比一个个复制要好些，写代码动手能力比较强的伙伴，可以考虑使用上面的sql查询代码来生成表格，然后用代码生成word文档，navicat premium破解版获取点击： navicat premium破解版下载

linux 定时任务备份至七牛
type: item
date: 2022-04-18T20:07:00+08:00
description: 场景生产数据定时备份的意义大家应该都是知道的，很多人备份只是备份到了本地，但是也会存在一定的隐患，比如客户一直不用系统，我们也不去注意，哪天服务器到期了过了几个月客户突然要用方向数据没了。。。使用到的工具主要看大家的服务器的安装情况，如果是安装了宝塔面板这种，有定时任务工具直接使用，而且也有免费的七牛云插件，设置起来超级简单，如果安装宝塔的不懂设置可以评论区留言，实在是太简单了本文就不讲了，说实话是会点鼠标就可以弄了基于linux系统内备份大概的意思就是你的mysql是自己用命令安装的。七牛平台shell脚本linux定时任务需要七牛云账号，用户需要自己创建，或者其它用其它云盘原理都是一样的（一）下载qshell工具并安装设置1. 工具下载说明文档与下载地址： 七牛工具下载 工具是七牛官方提供的，下载工具后传到服务器，主要看自己服务器的架构，我的服务是linux x86的，根据自己服务器去下载，把文件上传至服务目录/home/backup/shell 目录。并赋予权限chomd +x qshell2. 登录设置七牛云账号注意需要在工具目录下执行，如果需要任何目录执行需要添加环境变量可查看官方文档说明，更多说明以官方最新文档为准# 参数说明可自己根据情况修改 #ak :官方获取 #sk: 官方平台获取 #name : 任意用户名，不是七牛的账户，比如 db-test qshell account <ak> <sk> <name> #完成命令参考（二） shell编辑脚本在目录/home/backup/shell 下新建脚本backup.sh#!/bin/sh # mysql data backup script # # use mysqldump --help,get more detail. # 需要设置环境变量，crond中默认读取不到我们的一些环境 PATH=$PATH:/home/backup/shell export PATH dbname=<dbname> #备份文件目录 bakDir=/home/backup/sql logFile=/home/backup/backup.log month=` date +%Y%m ` # 七牛的备份目录，当前按数据库为一级目录，月份为2级目录如：dbname/202004/****.gz.sql qiniuPath=typecho_joe_theme/$month # 七牛空间名 qiniuBucket=<bucketName> datetime=`date +%Y%m%d%H%M%S` keepDay=7 echo "-------------------------------------------" >> $logFile echo $(date +"%y-%m-%d %H:%M:%S") >> $logFile echo "--------------------------" >> $logFile cd $bakDir bakFile=$dbname.$datetime.sql.gz # yum,apt-get,源码编译安装释放 mysqldump -u$user -p$password $dbname | gzip > $bakFile #docker安装执行方式,需要修改<dbname>为自己的数据库 #docker exec mysql5.6 sh -c 'exec mysqldump <dbname> -uroot -p"$MYSQL_ROOT_PASSWORD"' | gzip > $bakDir/$bakFile echo "数据库 [$dbname] 备份完成" >> $logFile echo "$bakDir/$bakFile" >> $logFile echo "开始上传备份文件至七牛云存储" >> $logFile #七牛上传命令，分片上传适用大文件，当前使用低频储存，具体命令可以查看文档 qshell rput $qiniuBucket $qiniuPath/$bakFile $bakDir/$bakFile --storage 1 | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" >> $logFile 2>&1 echo "删除${keepDay}天前的备份文件" >> $logFile find $bakDir -ctime +$keepDay >> $logFile find $bakDir -ctime +$keepDay -exec rm -rf {} \; echo " " >> $logFile echo " " >> $logFile 参考文献：qshell命令说…

【MySql】Specified key was too long; max key length is 767 bytes的解决方案
type: item
date: 2022-04-17T10:19:00+08:00
description: 问题背景由于业务需要，需要做数据库迁移，迁移由5.7版本得mysql到现有的mysql5.6版本，主要是因为更innodb_large_prefix 参数有关由于MySQL的InnoDB引擎表索引字段长度的限制为767字节，因此对于多字节字符集的大字段或者多字段组合，创建索引时会出现该问题。在5.6中innodb_large_prefix 默认关闭，在5.7中默认开启。在5.6中默认为 offSpecified key was too long; max key length is 767 bytes原来是主键的长度太长，最大长度仅支持767字节，注意，这里的是字节。那么，我定义一个主键是varchar(500)的字段，不管我使用utf8编码，那么500字符长度将占用5003的字节长度（utf8最多支持3个字节长度）；或是我使用utf8mb4编码，那么500字符长度将占用5004的字节长度（utf8mb4最多支持4个字节长度），都大大超过了767字节。如何去解决呢？先检查一下是不是数据库被限制了索引的大小，查询innodb_large_prefix这个字段，这个字段限制了索引前缀的大小。关闭此限制后，索引前缀的大小将可以达到3072字节。方法1：修改全局变量修改全局变量 ，当mysql重启后将失效，建议直接修改配置文件SHOW variables like 'innodb_large_prefix';如果查询的值是OFF的话 执行下面命令SET GLOBAL INNODB_LARGE_PREFIX = ON;另外，innodb_large_prefix这个属性在5.6上是默认关闭的，而在5.7上是默认开启的。执行完了 之后 还得查看当前的innodb_file_format引擎格式类型是不是BARRACUDA执行SHOW variables like 'innodb_file_format';如果不是的话则需要修改SET GLOBAL innodb_file_format = BARRACUDA;方法二：修改配置[mysqld] innodb_large_prefix = on innodb_file_format = BARRACUDA最后，创建表的时候，还需要指定表的 row format 格式为 Dynamic 或者 Compressed，如下示例：CREATE TABLE test( name varchar(500) CHARACTER SET utf8 COLLATE utf8_bin, PRIMARY KEY (`name `) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;版权声明：本文为CSDN博主「SunAlwaysOnline」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。参考原文链接：https://blog.csdn.net/qq_33591903/article/details/103927547

Mysql数据库误删/错删数据恢复-binlog日志使用
type: item
date: 2022-04-06T13:28:00+08:00
description: 一、binlog 基本认识MySQL的二进制日志可以说是MySQL最重要的日志了，它记录了所有的DDL和DML(除了数据查询语句)语句，以事件形式记录，还包含语句所执行的消耗的时间，MySQL的二进制日志是事务安全型的。一般来说开启二进制日志大概会有1%的性能损耗(参见MySQL官方中文手册 5.1.24版)。二进制有两个最重要的使用场景:MySQL Replication在Master端开启binlog，Mster把它的二进制日志传递给slaves来达到master-slave数据一致的目的，也就是大家比较常听到主从复制，和读写分离的应用场景数据恢复，通过使用mysqlbinlog工具来使恢复数据，也是大家说的数据恢复，用于数据误删找回的场景使用。二进制日志包括两类文件：二进制日志索引文件（文件名后缀为.index）用于记录所有的二进制文件，二进制日志文件（文件名后缀为.00000*）记录数据库所有的DDL和DML(除了数据查询语句)语句事件。二、开启binlog日志编辑打开mysql配置文件vi /usr/local/mysql/etc/my.cnf在[mysqld] 区块下，设置/添加 log-bin=mysql-bin 确认是打开状态(值 mysql-bin 是日志的基本名或前缀名)； #开启log日志 log-bin = mysql-bin #默认路径可修改 log_bin = /var/lib/mysql/mysql-bin.log #日志过期时间，设置为0则永不过期，默认设置不过期 expire_logs_days = 7 #模式 binlog_format = ROW #超过max_binlog_size或超过6小时会切换到下一序号文件 max_binlog_size = 100M #二进制日志缓冲大小,通过show status like 'binlog_%';查看调整写入磁盘的次数，写入磁盘为0最好 binlog_cache_size = 16M max_binlog_cache_size = 256M #改参数默认是打开的，在数据库启动后立即启动自动relay log恢复，在恢复过程中，创建一个新的relay log文件，将sql线程的位置初始化到新的relay log，并将i/o线程初始化到sql线程位置。 relay_log_recovery = 1 关于MYSQL中binlog_format参数说明重启mysqld服务使配置生效三、登录mysql服务器，通过mysql的变量配置表，查看二进制日志是否已开启登录服务器mysql -uroot -p123456 mysql> show variables like 'log_%'; +----------------------------------------+---------------------------------------+ | Variable_name | Value | +----------------------------------------+---------------------------------------+ | log_bin | ON | ------> ON表示已经开启binlog日志 | log_bin_basename | /usr/local/mysql/data/mysql-bin | | log_bin_index | /usr/local/mysql/data/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | log_error | /usr/local/mysql/data/martin.err | | log_output | FILE | | log_queries_not_using_indexes | OFF | | log_slave_updates | OFF | | log_slow_admin_statements | OFF | | log_slow_slave_statements | OFF | | log_throttle_queries_not_using_indexes | 0 | | log_warnings | 1 | +----------------------------------------+---------------------------------------+四、常用binlog日志操作命令1.查看所有binlog日志列表 mysql> show master logs;2.查看maste…

关于MYSQL中BINLOG_FORMAT的三种模式
type: item
date: 2022-04-06T13:15:15+08:00
description: MYSQL中BINLOG_FORMAT的三种模式mysql复制主要有三种方式：基于SQL语句的复制(statement-based replication, SBR)，基于行的复制(row-based replication, RBR)，混合模式复制(mixed-based replication, MBR)。对应的，binlog的格式也有三种：STATEMENT，ROW，MIXED。① STATEMENT模式（SBR）每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化，减少了binlog日志量，节约IO，提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数， last_insert_id()，以及user-defined functions(udf)等会出现问题)② ROW模式（RBR）不记录每条sql语句的上下文信息，仅需记录哪条数据被修改了，修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志，尤其是alter table的时候会让日志暴涨。③ MIXED模式（MBR）以上两种模式的混合使用，一般的复制使用STATEMENT模式保存binlog，对于STATEMENT模式无法复制的操作使用ROW模式保存binlog，MySQL会根据执行的SQL语句选择日志保存方式。binlog复制配置在mysql的配置文件my.cnf中，可以通过一下选项配置binglog相关代码如下 复制代码binlog_format = MIXED //binlog日志格式，mysql默认采用statement，建议使用mixedlog-bin = /data/mysql/mysql-bin.log //binlog日志文件expire_logs_days = 7 //binlog过期清理时间max_binlog_size = 100m //binlog每个日志文件大小binlog_cache_size = 4m //binlog缓存大小max_binlog_cache_size = 512m //最大binlog缓存大小三 MIXED说明对于执行的SQL语句中包含now()这样的时间函数，会在日志中产生对应的unix_timestamp()*1000的时间字符串，slave在完成同步时，取用的是sqlEvent发生的时间来保证数据的准确性。另外对于一些功能性函数slave能完成相应的数据同步，而对于上面指定的一些类似于UDF函数，导致Slave无法知晓的情况，则会采用ROW格式存储这些Binlog，以保证产生的Binlog可以供Slave完成数据同步。现在来比较以下 SBR 和 RBR 2中模式各自的优缺点：SBR 的优点：历史悠久，技术成熟binlog文件较小binlog中包含了所有数据库更改信息，可以据此来审核数据库的安全等情况binlog可以用于实时的还原，而不仅仅用于复制主从版本可以不一样，从服务器版本可以比主服务器版本高SBR 的缺点：不是所有的UPDATE语句都能被复制，尤其是包含不确定操作的时候。调用具有不确定因素的 UDF 时复制也可能出问题使用以下函数的语句也无法被复制：LOAD_FILE()UUID()USER()FOUND_ROWS()SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)INSERT ... SELECT 会产生比 RBR 更多的行级锁复制需要进行全表扫描(WHERE 语句中没有使用到索引)的 UPDATE 时，需要比 RBR 请求更多的行级锁对于有 AUTO_INCREMENT 字段的 InnoDB表而言，INSERT 语句会阻塞其他 INSERT 语句对于一些复杂的语句，在从服务器上的耗资源情况会更严重，而 RBR 模式下，只会对那个发生变化的记录产生影响存储函数(不是存储过程)在被调用的同时也会执行一次 NOW() 函数，这个可以说是坏事也可能是好事确定了的 UDF 也需要在从服务器上执行数据表必须几乎和主服务器保持一致才行，否则可能会导致复制出错执行复杂语句如果出错的话，会消耗更多资源RBR 的优点：任何情况都可以被复制，这对复制来说是最安全可靠的和其他大多数数据库系统的复制技术一样多数情况下，从服务器上的表如果有主键的话，复制就会快了很多复制以下几种语句时的行锁更少：INSERT ... SELECT包含 AUTO_INCREMENT 字段的 INSERT没有附带条件或者并没有修改很多记录的 UPDATE 或 DELETE 语句执行 INSERT，UPDATE，DELETE 语句时锁更少…

Mysql中definer引起的视图查询提示密码错误
type: item
date: 2022-04-06T12:57:00+08:00
description: 这个问题会导致以下几个问题出现。mysqsl查询视图，函数时显示密码错误迁移数据库时，显示查询密码错误等1.mysql中的definer是什么，有什么作用？我们在mysql创建view、trigger、function、procedure、event时都会定义一个Definer=‘xxx’,类似如下：CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`%` SQL SECURITY DEFINER VIEW `v_ questions` AS SELECT `q`.`id` AS `id`, `q`.`title` AS `title` FROM Test q; -- 或者像这样的： CREATE DEFINER=`root`@`%` PROCEDURE `user_count`() LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN select count(*) from mysql.user; END加红的部分SQL SECURITY 其实后面有两个选项，一个为DEFINER，一个为INVOKERSQL SECURITY { DEFINER | INVOKER } ：指明谁有权限来执行。DEFINER 表示按定义者拥有的权限来执行INVOKER 表示用调用者的权限来执行。默认情况下，系统指定为DEFINER 以存储过程为例：（1）MySQL存储过程是通过指定SQL SECURITY子句指定执行存储过程的实际用户；（2）如果SQL SECURITY子句指定为DEFINER，存储过程将使用存储过程的DEFINER执行存储过程，验证调用存储过程的用户是否具有存储过程的execute权限和DEFINER用户是否具有存储过程引用的相关对象的权限；（3）如果SQL SECURITY子句指定为INVOKER，那么MySQL将使用当前调用存储过程的用户执行此过程，并验证用户是否具有存储过程的execute权限和存储过程引用的相关对象的权限；（4）如果不显示的指定SQL SECURITY子句，MySQL默认将以DEFINER执行存储过程。我们来看下面几个小例子。先授权一个： grant all on testdb.* to 'user1'@'%' identified by '000000' with grant option; 然后我们创建一个存储过程如下： USE `testdb`; DROP procedure IF EXISTS `user_count`; DELIMITER $$ USE `testdb`$$ CREATE DEFINER=`root`@`%` PROCEDURE `user_count`() LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY INVOKER COMMENT '' BEGIN select count(*) from mysql.user; END$$ DELIMITER ;用root帐号登陆： mysql> use testdb; Database changed mysql> call user_count(); +----------+ | count(*) | +----------+ | 3 | +----------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) 可以正常查询出来。 我们再用user1进行登陆： mysql> use testdb; Database changed mysql> call user_count(); ERROR 1142 (42000): SELECT command denied to user 'user1'@'localhost' for table 'user' 现系统报错查询不到了，这是因为我们在上述定义的SQL SECURITY值为INVOKER，存储过程执行过程中会以user1具有的权限来执行，其中调用到了mysql的库，而我们的user1帐户只有testdb库的使用权限，所以会返回失败。我们把上面的invoker改为definer再来试一下：update mysql.proc set security_type='DEFINER' where db='testdb' and name='user_count'; 再次用user1进行登陆： mysql> use testdb; Database changed mysql> call user_c…

mysqlbinlog: [ERROR] unknown variable 'default-character-set=utf8mb4'如何解决？
type: item
date: 2022-04-05T22:29:00+08:00
description: 原因：mysqlbinlog这个工具无法识别binlog中的配置中的default-character-set=utf8mb4这个指令。添加 --no-defaults 参数mysqlbinlog --no-defaults mysql-bin.000001 > 01.sql注意：加入该项会导致utf8mb4 变为空字符串，会影响数据一致性问题