-
问题描述这是关于MySQL事务特性的常见面试题面试官通过这个问题考察你对事务ACID特性、隔离级别和事务控制的理解通常会追问事务隔离级别和并发控制机制核心答案MySQL事务具有以下特性:ACID特性原子性(Atomicity):事务是不可分割的工作单位一致性(Consistency):事务执行前后数据库状态保持一致隔离性(Isolation):事务之间互不干扰持久性(Durability):事务提交后永久生效隔离级别READ UNCOMMITTED:读未提交READ COMMITTED:读已提交REPEATABLE READ:可重复读(InnoDB默认)SERIALIZABLE:串行化事务控制BEGIN/START TRANSACTION:开始事务COMMIT:提交事务ROLLBACK:回滚事务SAVEPOINT:设置保存点详细解析1. ACID特性详解原子性(Atomicity)事务中的所有操作要么全部成功,要么全部失败通过undo log实现回滚操作保证数据库状态的一致性一致性(Consistency)事务执行前后数据库必须处于一致状态通过约束、触发器、级联等机制保证包括实体完整性、参照完整性等隔离性(Isolation)事务之间互不干扰通过锁机制和MVCC实现不同隔离级别提供不同的隔离保证持久性(Durability)事务提交后对数据库的修改是永久的通过redo log实现即使系统崩溃也能恢复2. 隔离级别详解READ UNCOMMITTED最低隔离级别可能读取到未提交的数据(脏读)性能最好,但数据一致性最差READ COMMITTED只能读取已提交的数据解决脏读问题可能出现不可重复读REPEATABLE READInnoDB默认隔离级别解决脏读和不可重复读可能出现幻读(InnoDB通过MVCC解决)SERIALIZABLE最高隔离级别完全串行化执行解决所有并发问题,但性能最差3. 事务控制详解事务开始-- 显式开始事务 BEGIN; -- 或 START TRANSACTION; -- 设置隔离级别 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 事务提交-- 提交事务 COMMIT; -- 提交并释放锁 COMMIT AND CHAIN; 事务回滚-- 回滚整个事务 ROLLBACK; -- 回滚到保存点 ROLLBACK TO SAVEPOINT savepoint_name; 保存点-- 设置保存点 SAVEPOINT savepoint_name; -- 释放保存点 RELEASE SAVEPOINT savepoint_name; 常见追问Q1: InnoDB如何实现MVCC?A:通过隐藏列(DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID)实现使用ReadView判断数据可见性不同隔离级别使用不同的ReadView策略通过undo log实现版本链Q2: 什么是幻读?如何解决?A:幻读:同一事务中,相同的查询条件返回不同的行数InnoDB通过Next-Key Lock解决幻读在REPEATABLE READ级别下,通过间隙锁防止幻读也可以使用SERIALIZABLE隔离级别Q3: 事务隔离级别如何选择?A:需要最高并发性能:READ UNCOMMITTED需要避免脏读:READ COMMITTED需要避免不可重复读:REPEATABLE READ需要完全隔离:SERIALIZABLE大多数应用使用REPEATABLE READ扩展知识事务相关参数-- 查看事务隔离级别 SELECT @@transaction_isolation; -- 查看自动提交设置 SELECT @@autocommit; -- 查看锁等待超时时间 SELECT @@innodb_lock_wait_timeout; 死锁检测-- 查看死锁日志 SHOW ENGINE INNODB STATUS; -- 设置死锁检测 SET GLOBAL innodb_deadlock_detect = ON; 实际应用示例场景一:转账事务-- 开始事务 START TRANSACTION; -- 扣减账户A余额 UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A'; -- 增加账户B余额 UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B'; -- 提交事务 COMMIT; 场景二:批量处理-- 开始事务 START TRANSACTION; -- 设置保存点 SAVEPOINT before_update; -- 更新数据 UPDATE large_table SET status = 'processed' WHERE id < 1000; -- 如果更新成功,继续处理 SAVEPOINT before_insert; -- 插入新数据 INSERT INTO log_table (message) VALUES ('Processed 1000 records'); -- 提交事务 COMMIT; 总结MySQL事务具有ACID特性提供四种隔离级别,InnoDB默认REPEATABLE READ通过锁机制和MVCC实现并发控制支持事务的提交、回滚和保存点合理选择隔离级别和事务控制策略记忆技巧事务特性ACID,原子一致隔离持久: 原子性要全成功,一致性要状态同 隔离性要互不扰,持久性要永久存 隔离级别四兄弟,性能一致成反比 并发问题三兄弟,脏读不可重复幻读 事务控制要记清,开始提交回滚点 保存点可回滚,事务嵌套要小心面试技巧按顺序说明ACID特性重点解释不同隔离级别的特点结合实际案例说明事务控制讨论并发问题和解决方案
-
问题描述这是关于InnoDB存储引擎特性的常见面试题面试官通过这个问题考察你对InnoDB底层存储结构的理解通常会追问不同行格式的特点和适用场景核心答案InnoDB支持四种行格式:COMPACT默认行格式存储效率高,空间占用小支持变长字段和NULL值适合大多数应用场景REDUNDANT兼容旧版本的行格式存储效率较低支持所有数据类型主要用于向后兼容DYNAMIC支持大字段(BLOB/TEXT)的溢出存储行溢出时只存储20字节指针适合包含大字段的表空间利用率高COMPRESSED支持数据压缩节省存储空间适合数据量大且读多写少的场景压缩比可达50%以上详细解析1. COMPACT行格式COMPACT行格式是InnoDB的默认行格式,它采用紧凑的存储方式,通过以下方式优化存储空间:变长字段只存储实际长度NULL值不占用存储空间使用位图标记NULL值记录头信息占用5字节2. REDUNDANT行格式REDUNDANT行格式是旧版本InnoDB使用的行格式,它的特点是:固定长度字段存储NULL值占用固定空间记录头信息占用6字节兼容性好,但存储效率低3. DYNAMIC行格式DYNAMIC行格式是MySQL 5.7引入的新行格式,特别适合处理大字段:大字段(BLOB/TEXT)存储在溢出页行内只存储20字节的指针支持行溢出空间利用率高4. COMPRESSED行格式COMPRESSED行格式在DYNAMIC基础上增加了数据压缩功能:使用zlib算法压缩数据支持表空间压缩压缩比可达50%以上适合读多写少的场景常见追问Q1: 如何选择合适的行格式?A:一般应用选择COMPACT格式包含大字段的表选择DYNAMIC格式需要压缩存储的选择COMPRESSED格式需要兼容旧版本的选择REDUNDANT格式Q2: 行格式对性能有什么影响?A:COMPACT格式读写性能最好DYNAMIC格式适合大字段操作COMPRESSED格式读性能好,写性能较差REDUNDANT格式性能最差Q3: 如何修改表的行格式?A:-- 修改表的行格式 ALTER TABLE table_name ROW_FORMAT=DYNAMIC; -- 创建表时指定行格式 CREATE TABLE table_name ( ... ) ROW_FORMAT=COMPRESSED; 扩展知识行格式配置参数-- 查看默认行格式 SHOW VARIABLES LIKE 'innodb_default_row_format'; -- 修改默认行格式 SET GLOBAL innodb_default_row_format = 'DYNAMIC'; 行格式存储结构-- 查看表的行格式 SHOW TABLE STATUS LIKE 'table_name'; -- 查看表空间信息 SELECT * FROM information_schema.INNODB_TABLESPACES WHERE NAME LIKE '%table_name%'; 实际应用示例场景一:大字段表优化-- 创建包含大字段的表,使用DYNAMIC格式 CREATE TABLE blog_posts ( id BIGINT PRIMARY KEY, title VARCHAR(255), content TEXT, created_at TIMESTAMP ) ROW_FORMAT=DYNAMIC; -- 修改现有表为DYNAMIC格式 ALTER TABLE blog_posts ROW_FORMAT=DYNAMIC; 场景二:数据压缩存储-- 创建压缩表 CREATE TABLE archive_data ( id BIGINT PRIMARY KEY, data JSON, created_at TIMESTAMP ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; -- 修改现有表为压缩格式 ALTER TABLE archive_data ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; 总结InnoDB支持四种行格式:COMPACT、REDUNDANT、DYNAMIC和COMPRESSEDCOMPACT是默认格式,适合大多数场景DYNAMIC适合包含大字段的表COMPRESSED适合需要压缩存储的场景选择行格式需要考虑存储效率和性能需求记忆技巧InnoDB行格式四兄弟,存储效率各不同: COMPACT是默认,空间效率最高级 REDUNDANT为兼容,存储效率最低级 DYNAMIC为大字段,溢出存储最合适 COMPRESSED能压缩,读多写少最适宜 选择格式要记清,普通表用COMPACT 大字段用DYNAMIC,压缩存储COMPRESSED 兼容旧版REDUNDANT,新项目别用它面试技巧按顺序说明四种行格式的特点重点解释不同行格式的适用场景结合实际案例说明如何选择行格式讨论行格式对性能的影响
-
问题描述这是关于MySQL查询执行原理的常见面试题面试官通过这个问题考察你对SQL语句执行过程的理解通常会追问Query Cache的工作原理和影响核心答案SQL语句在MySQL中的执行过程:连接器阶段负责建立客户端与MySQL服务器的连接进行用户身份认证检查用户权限维护连接状态查询缓存阶段检查Query Cache中是否存在完全相同的SQL语句如果命中缓存,直接返回结果如果未命中,继续执行后续步骤解析阶段词法分析:将SQL语句分解成token语法分析:检查SQL语法是否正确生成解析树优化阶段优化器分析执行计划选择最优的索引和连接顺序生成执行计划执行阶段执行器根据执行计划调用存储引擎接口存储引擎执行具体的数据操作返回结果集详细解析1. 连接器(Connector)工作原理连接器负责处理客户端与MySQL服务器的连接。当客户端尝试连接MySQL时,连接器会验证用户名和密码,检查该用户是否有权限连接到MySQL服务器。连接成功后,连接器会负责管理连接的状态,包括维护连接的生命周期、执行重连操作、处理连接池等。连接的权限在连接建立时确定,之后修改用户权限不会影响已建立的连接。2. Query Cache工作原理Query Cache是MySQL的一个查询缓存机制,它缓存SELECT语句的查询结果。当执行相同的SELECT语句时,MySQL会直接返回缓存的结果,而不需要重新执行查询。Query Cache的命中率受表数据变化频率影响,频繁更新的表不适合使用Query Cache。3. 解析和优化过程SQL语句的解析和优化过程包括词法分析、语法分析、语义分析、查询重写、优化器决策等步骤。优化器会考虑索引选择、表连接顺序、子查询优化等因素,生成最优的执行计划。4. 执行过程详解执行器根据优化器生成的执行计划,调用存储引擎接口执行具体操作。对于SELECT查询,执行器会按照执行计划逐步获取数据,并可能使用临时表、排序等操作处理结果。常见追问Q1: 连接器如何管理连接?A:维护连接的生命周期,默认空闲超时时间为8小时(wait_timeout参数)处理身份认证和权限验证管理连接状态和会话变量支持连接复用和连接池技术控制最大连接数(max_connections参数)Q2: Query Cache在什么情况下会被清空?A:当表数据被修改(INSERT/UPDATE/DELETE)时当表结构被修改(ALTER TABLE)时当执行FLUSH QUERY CACHE命令时当Query Cache内存不足时当MySQL服务器重启时Q3: 为什么MySQL 8.0移除了Query Cache?A:Query Cache的锁竞争严重,影响并发性能缓存失效机制导致频繁的缓存清理对于频繁更新的表,Query Cache命中率低现代应用通常使用应用层缓存(如Redis)多核CPU环境下,Query Cache的锁竞争问题更严重Q4: 如何判断SQL语句是否使用了Query Cache?A:使用SHOW STATUS LIKE 'Qcache%'查看Query Cache状态使用EXPLAIN查看执行计划,如果使用了Query Cache,type列会显示"system"通过慢查询日志分析查询执行时间使用SHOW PROFILE查看查询执行过程扩展知识连接器配置参数-- 查看连接相关参数 SHOW VARIABLES LIKE 'max_connections'; -- 最大连接数 SHOW VARIABLES LIKE 'wait_timeout'; -- 空闲连接超时时间 SHOW VARIABLES LIKE 'interactive_timeout'; -- 交互式连接超时时间 -- 查看当前连接状态 SHOW PROCESSLIST; -- 显示当前连接的会话信息 Query Cache配置参数-- 查看Query Cache相关参数 SHOW VARIABLES LIKE 'query_cache%'; -- 重要参数说明 query_cache_type = 1 -- 启用Query Cache query_cache_size = 64M -- Query Cache大小 query_cache_limit = 1M -- 单个查询结果最大缓存大小 query_cache_min_res_unit = 4K -- 分配内存块的最小单位 SQL执行过程示例-- 示例1:使用Query Cache的查询 SELECT * FROM users WHERE id = 1; -- 第一次执行,会缓存结果 SELECT * FROM users WHERE id = 1; -- 第二次执行,直接从缓存返回 -- 示例2:导致Query Cache失效的操作 UPDATE users SET name = 'new_name' WHERE id = 1; -- 更新操作会使相关缓存失效 实际应用示例场景一:连接管理-- 查看当前连接数 SHOW STATUS LIKE 'Threads_connected'; -- 查看连接历史峰值 SHOW STATUS LIKE 'Max_used_connections'; -- 优化连接管理的配置 SET GLOBAL max_connections = 500; -- 增加最大连接数 SET GLOBAL wait_timeout = 600; -- 减少空闲连接的超时时间,释放更多资源 场景二:Query Cache性能分析-- 查看Query Cache状态 SHOW STATUS LIKE 'Qcache%'; -- 计算Query Cache命中率 SELECT (Qcache_hits / (Qcache_hits + Qcache_inserts)) * 100 AS hit_rate FROM ( SELECT variable_value AS Qcache_hits FROM information_schema.global_status WHERE variable_name = 'Qcache_hits' ) AS hits, ( SELECT variable_value AS Qcache_inserts FROM information_schema.global_status WHERE variable_name = 'Qcache_inserts' ) AS inserts; 场景三:SQL执行过程分析-- 使用EXPLAIN分析执行计划 EXPLAIN SELECT u.*, o.order_count FROM users u LEFT JOIN ( SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id ) o ON u.id = o.user_id WHERE u.status = 'active'; -- 使用SHOW PROFILE分析执行过程 SET profiling = 1; SELECT * FROM large_table WHERE id > 1000; SHOW PROFILE; 总结SQL语句执行包括连接器、查询缓存、解析、优化、执行五个主要阶段连接器负责身份认证、权限验证和维护连接状态Query Cache可以提升重复查询性能,但存在并发和失效问题MySQL 8.0移除了Query Cache,建议使用应用层缓存理解SQL执行过程有助于优化查询性能和连接管理记忆技巧SQL执行五步走,连接缓存解析优化执行: 连接器管认证,Query Cache查缓存 解析器做分析,优化器选计划 执行器调引擎,结果返回客户端 Query Cache要记清,命中直接返结果 未命中继续走,解析优化再执行 MySQL 8.0已移除,应用缓存更合适面试技巧按顺序说明SQL执行的各个阶段,强调连接器和Query Cache的重要性重点解释连接器的职责和Query Cache的工作原理与限制结合实际案例说明如何优化SQL执行和连接管理讨论MySQL 8.0移除Query Cache的原因
-
问题描述这是关于MySQL查询性能的常见面试题面试官通过这个问题考察你对数据库查询执行原理的理解通常会追问如何优化多表JOIN查询性能核心答案多表JOIN对MySQL性能的影响:系统资源消耗增加CPU和内存消耗,特别是连接表数量较多时可能导致临时表创建,增加I/O操作执行效率影响连接表数量越多,执行计划复杂度指数级增长多表JOIN可能导致全表扫描,降低查询效率影响因素JOIN类型(内连接、外连接)影响性能连接条件和索引使用情况决定效率数据量和分布对性能有显著影响详细解析1. JOIN的工作原理MySQL多表JOIN的执行过程为嵌套循环连接(Nested Loop Join)、基于块的嵌套循环连接(Block Nested Loop Join)、哈希连接(MySQL 8.0.18+)。不同JOIN类型中,内连接(INNER JOIN)通常效率较高,左/右外连接(LEFT/RIGHT JOIN)次之,全外连接(FULL JOIN,MySQL通过UNION模拟)效率最低。2. 影响JOIN性能的关键因素JOIN性能受到连接条件上的索引使用情况、连接表的大小和顺序、JOIN类型选择、WHERE条件过滤效率、缓冲区大小配置等多方面影响。其中JOIN条件字段上缺少索引和不恰当的连接顺序是导致性能问题的最常见原因。3. 多表JOIN性能优化策略优化JOIN查询的关键策略包括在JOIN条件字段上建立适当索引、控制JOIN表的数量(尽量不超过5个)、使用小表驱动大表、用EXPLAIN分析执行计划、适当增大join_buffer_size参数等。对于超大表JOIN可考虑分而治之策略或预先聚合。常见追问Q1: MySQL中JOIN的实现机制有哪些?A:嵌套循环连接(Nested Loop Join):最基本的实现,对外表的每一行,都去内表查找匹配的行基于块的嵌套循环连接(Block Nested Loop Join):将外表数据分块加载到join buffer中,减少内表访问次数哈希连接(Hash Join):MySQL 8.0.18+引入,适合大表等值连接,先构建哈希表再匹配排序合并连接(Sort Merge Join):MySQL未直接实现,但优化器可能通过排序后再连接来模拟Q2: 如何判断JOIN查询是否需要优化?A:执行EXPLAIN分析,关注type列(ALL表示全表扫描)和rows列(扫描行数过多)查询执行时间明显过长或CPU使用率高临时表使用量大且频繁发生磁盘临时表Extra列出现"Using filesort"或"Using temporary"对于复杂的JOIN可使用Profile工具分析资源消耗Q3: LEFT JOIN和INNER JOIN在性能上有什么差异?A:INNER JOIN通常效率更高,因为可以更灵活地选择驱动表LEFT JOIN必须以左表为驱动表,限制了优化器的选择LEFT JOIN可能返回更多的行(包括不匹配行),增加后续处理成本INNER JOIN允许优化器应用更多连接顺序优化当左表较小时,LEFT JOIN和INNER JOIN性能差异不大当使用了合适的索引时,两者性能差异会减小扩展知识JOIN优化示例-- 优化前:没有合适索引的JOIN SELECT o.order_id, c.customer_name, p.product_name FROM orders o LEFT JOIN customers c ON o.customer_id = c.id LEFT JOIN order_items oi ON o.order_id = oi.order_id LEFT JOIN products p ON oi.product_id = p.id WHERE o.created_at > '2023-01-01'; -- 优化后:确保JOIN字段有索引 -- 在customers表的id字段、order_items表的order_id字段、products表的id字段上创建索引 -- 在orders表的created_at字段上创建索引用于WHERE过滤 EXPLAIN输出解读+----+-------------+-------+------+---------------+------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------+ | 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 1000 | Using where | | 1 | SIMPLE | c | ALL | PRIMARY | NULL | NULL | NULL | 100 | Using join buffer | | 1 | SIMPLE | oi | ALL | NULL | NULL | NULL | NULL | 2000 | Using where; Using join buffer | | 1 | SIMPLE | p | ALL | PRIMARY | NULL | NULL | NULL | 200 | Using where; Using join buffer | +----+-------------+-------+------+---------------+------+---------+------+------+-------+ 上面的EXPLAIN结果显示所有表连接类型都是ALL(全表扫描),未使用索引,且使用了join buffer,这表明JOIN性能非常差。实际应用示例场景一:电商订单查询优化-- 优化前:多表JOIN且无索引 SELECT o.order_number, c.name, p.product_name, o.total_amount FROM orders o JOIN customers c ON o.customer_id = c.customer_id JOIN order_items oi ON o.order_id = oi.order_id JOIN products p ON oi.product_id = p.product_id WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'; -- 优化后:添加索引并限制结果集 CREATE INDEX idx_customer_id ON orders(customer_id); CREATE INDEX idx_order_id ON order_items(order_id); CREATE INDEX idx_product_id ON order_items(product_id); CREATE INDEX idx_order_date ON orders(order_date); -- 使用子查询减少JOIN表数量 SELECT o.order_number, c.name, (SELECT GROUP_CONCAT(p.product_name) FROM order_items oi JOIN products p ON oi.product_id = p.product_id WHERE oi.order_id = o.order_id) AS products, o.total_amount FROM orders o JOIN customers c ON o.customer_id = c.customer_id WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31' LIMIT 1000; 场景二:报表查询优化-- 优化前:复杂多表JOIN SELECT d.department_name, COUNT(e.employee_id) as emp_count, AVG(s.salary) as avg_salary, MAX(s.salary) as max_salary FROM employees e JOIN departments d ON e.department_id = d.department_id JOIN salaries s ON e.employee_id = s.employee_id JOIN emp_performance p ON e.employee_id = p.employee_id WHERE YEAR(s.effective_date) = 2023 GROUP BY d.department_name; -- 优化后:使用汇总表 CREATE TABLE department_summary ( department_id INT, department_name VARCHAR(100), emp_count INT, avg_salary DECIMAL(10,2), max_salary DECIMAL(10,2), year INT, updated_at TIMESTAMP ); -- 定期更新汇总表 INSERT INTO department_summary SELECT d.department_id, d.department_name, COUNT(e.employee_id), AVG(s.salary), MAX(s.salary), YEAR(s.effective_date), NOW() FROM employees e JOIN departments d ON e.department_id = d.department_id JOIN salaries s ON e.employee_id = s.employee_id WHERE YEAR(s.effective_date) = 2023 GROUP BY d.department_id, d.department_name, YEAR(s.effective_date); -- 查询汇总表而非多表JOIN SELECT department_name, emp_count, avg_salary, max_salary FROM department_summary WHERE year = 2023; 总结多表JOIN会显著增加查询复杂度和资源消耗JOIN性能主要受索引、表大小、连接条件影响优化JOIN查询需从索引、表顺序、JOIN类型三方面入手对于复杂报表可使用汇总表策略避免多表JOIN记忆技巧多表JOIN性能差,资源消耗要记清: CPU内存磁盘IO,网络带宽都要用 优化策略要记牢,索引添加最重要 小表驱动大表好,子查询来替代JOIN 分区分表要考虑,缓存结果更高效 JOIN类型要分清,内连接效率最高 外连接要谨慎用,交叉连接最耗时面试技巧先说明JOIN的基本原理和实现方式解释JOIN性能瓶颈和资源消耗详细讲解优化JOIN的具体策略和案例结合实际项目经验说明优化效果
-
一、数据库基础1. 什么是数据库数据库 是一个有组织的集合,用于存储和管理数据的系统。它是一个软件系统,被设计用来存储、检索和管理数据,并提供数据的快速访问和处理。数据库可以被看作是一种特殊的文件系统,但与传统的文件系统不同的是:它能够更加高效的存储和管理大量结构化数据。数据库主要由数据库管理系统(DBMS)和数据库组成:数据库管理系统(DBMS):数据库管理系统是数据库的核心组成部分。它是一种软件系统,用于管理数据库的创建、维护、访问和操作。DBMS提供了一组功能,允许用户定义数据结构、存储数据、检索数据、更新数据、维护数据完整性、实施安全性控制、备份和恢复数据等。常见的DBMS包括MySQL、Oracle、SQL Server、PostgreSQL、SQLite等。不同的DBMS可能支持不同的数据模型,如关系型、文档型、图形型等,以满足不同类型的应用需求。数据库:数据库是一个有组织的数据集合,其中包含一个或多个数据表,每个数据表存储特定类型的数据。数据库用于持久性地存储和管理数据。数据可以以结构化的方式存储,允许用户定义数据表的结构、字段和数据类型。数据库中的数据可以根据需要进行增加、修改、删除和查询。数据库可以用于存储各种类型的数据,包括文本、数字、图像、音频、视频等。2. 数据库和文件存储数据用文件就可以了,为什么还要弄个数据库?文件保存数据 有以下几个缺点:文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便数据库相比于传统的文件存储系统具有重要的优点如下:数据结构化和一致性: 数据库强制数据以一种结构化的方式存储,这有助于确保数据的一致性和准确性。文件存储系统通常不提供此类数据结构化支持。数据完整性: 数据库管理系统(DBMS)提供了强大的数据完整性约束,以确保数据的有效性。这包括主键、外键、唯一性约束等。数据共享: 多个用户或应用程序可以同时访问数据库,而不会破坏数据的完整性。数据库提供了并发控制机制来管理同时访问数据的多个用户。数据安全性: 数据库可以提供用户身份验证和访问控制,以保护敏感数据免受未经授权的访问。文件存储通常没有这种级别的安全性。高性能和优化查询: 数据库系统经过优化,能够高效地处理数据检索和复杂查询。文件系统通常没有这种查询优化功能。数据冗余减少: 数据库减少了数据冗余,因为相同数据只存储一次,而且可以通过外键建立关系,从而减少了数据存储和更新的复杂性。数据一致性维护: 数据库提供了事务处理,允许多个操作被作为一个单一的、原子性的工作单元来执行。这有助于保持数据的一致性,即使在系统出现故障的情况下。备份和恢复: 数据库提供了备份和恢复功能,以保护数据免受丢失或损坏。文件存储通常需要手动管理备份。数据可扩展性: 数据库系统可以根据需求进行扩展,以处理大规模数据,而不会导致性能下降。数据查询和分析: 数据库允许执行复杂的查询和分析操作,以从数据中提取有用的信息。这是文件存储系统所不具备的功能。3. 主流数据库(关系型数据库)SQL Sever: 微软的产品,.Net程序员的最爱,中大型项目。Oracle: 甲骨文产品,适合大型项目,复杂的业务逻辑,并发一般来说不如MySQL。MySQL:世界上最受欢迎的数据库,属于甲骨文,并发性好,不适合做复杂的业务。主要用在电商,SNS,论坛。对简单的SQL处理效果好。PostgreSQL :加州大学伯克利分校计算机系开发的关系型数据库,不管是私用,商用,还是学术研究使用,可以免费使用,修改和分发。SQLite: 是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。H2: 是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中mysql 是一套给我们提供数据存取的服务的网络程序。数据库一般指的是,在磁盘或者内存中存储的特点结构组织的数据——将来在磁盘上存储的一整套数据库方案。数据库服务——mysqld一般文件确实提供了数据的存储功能,但是文件没有提供非常好的数据管理能力(用户角度)数据库的本质: 对数据内容存储的一套解决方案,用户将字段或者要求交给mysql,mysql再将要求交给mysqld服务端,最后mysqld再将结果返回给mysql,然后由mysql返回给用户。二、MySQL的基本使用1. 连接服务器mysql -h 127.0.0.1 -P 3306 -u root -p注意:如果没有写 -h 127.0.0.1 默认是连接本地如果没有写 -P 3306 默认是连接3306端口号2. 服务器管理执行 win+r 输入 services.msc 打开服务管理器通过下图左侧停止,暂停,重启动按钮进行服务管理3. 服务器、数据库、表关系所谓安装数据库服务器,只是在机器上安装了一个数据库管理系统程序,这个管理程序可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库中创建多个表,以保存程序中实体的数据。数据库服务器、数据库和表的关系如下:4. 使用案例💕 创建数据库:create database helloworld;其中,helloworld是要创建的新数据库的名称,执行该语句后,MySQL服务器将在其文件系统上创建一个新的数据库目录,并在其中存储有关该数据库的元数据信息。然后,可以使用该数据库执行其他 SQL 操作,如创建表格、插入数据等。在创建数据库时,还可以通过可选的参数来指定其他属性,例如字符集、校对规则等。💕 使用数据库:use helloworld;helloworld是指要使用的数据库的名称,在MySQL服务器中,可以同时存在多个数据库,使用use语句可以让用户指定当前要使用哪个数据库,从而执行该数据库中的SQL操作。在使用use语句之前,必须先创建要使用的数据库。💕 显示当前使用的数据库:select database();database()是一个SQL函数,用于返回当前使用的数据库的名称。💕 创建数据库表create table 语句用于在关系型数据库中创建新的数据表。数据表是用于存储和组织数据的一种结构化对象,其由列和行组成。以下是一个简单的 create table 语句的例子,创建一个名为 students 的数据表,该表包 含 id、name 和 age 三个列:💕 显示数据库中所有表:show tablespowershell这里我们需要注意的是:这里的 “Tables_in_数据库名” 中的数据库名表示的是当前使用的数据库名称。💕 向表中插入数据:insert into student (id, name, gender) values (1, '张三', '男');insert into student (id, name, gender) values (2, '李四', '女');insert into student (id, name, gender) values (3, '王五', '男');插入的值必须与数据表中列的数据类型匹配,否则会出现错误,同时,如果插入的值中包含单引号等特殊字符,需要进行转义处理。💕 查询数据表:select * from table_name;💕 获取数据表的结构信息:desc table_name;执行该语句后,将返回一个结果集,其中包含数据表的结构信息。结果集中包含以下列:Field、Type、Null、Key、Default、Extra。\n\nField:数据表中列的名称。Type:数据表中列的数据类型。Null:列是否允许为空。Key:列是否为主键或索引。Default:列的默认值。Extra:包含有关列的其他信息。三、数据的逻辑存储和实际存储逻辑存储数据库的数据逻辑存储是指在数据库中,如何将数据逻辑地组织和存储的问题。它是数据库设计的一个重要方面,对数据库的性能、可靠性和可扩展性等方面都有重要影响。数据逻辑存储主要是通过表、视图、索引等方式实现的。具体来说,每个数据库包含多个数据表,每个数据表包含多个数据行和数据列,每个数据列定义了数据类型和其他属性。数据表之间可以通过关联关系进行连接,形成视图。而索引则是一种数据结构,用于快速定位和访问数据表中的数据。实际存储数据库的数据实际存储结构包括数据页和数据行。数据页是数据库管理系统存储数据的最小单位,通常是固定大小的二进制文件。每个数据页通常包含多个数据行和一些元数据信息。数据库会将数据表中的数据按照数据页的大小进行分割和存储,以提高数据的访问效率。\n\n数据行是数据表中的一条记录,也是数据库中存储数据的基本单位。每个数据行包含若干个列,每个列对应一个数据类型的值。数据行可以看作是数据库中的一个对象,它具有唯一的标识符和属性。数据库的数据实际存储结构通常是由数据库管理系统自动维护的,用户只需要使用 SQL 语句进行操作即可。不过,在进行数据库设计时,需要考虑数据的存储方式和结构,以便提高数据库的性能和可维护性。四、MySQL的架构MySQL 是一个可移植的数据库,几乎能在当前所有的操作系统上运行,如 Unix/Linux、Windows、Mac 和 Solaris。各种系统在底层实现方面各有不同,但是 MySQL 基本上能保证在各个平台上的物理体系结构的一致性。客户端:客户端是 MySQL 的用户界面,它允许用户与 MySQL 服务器进行交互。MySQL 客户端可以是命令行工具,如 mysql 或 mysqladmin,也可以是可视化工具,如MySQL Workbench。服务端:MySQL 的服务端包括连接管理器、查询分析器、查询缓存、解析器、优化器、执行器等组件。当客户端连接到 MySQL 服务器时,连接管理器接收并处理连接请求。一旦连接建立,查询分析器将解析和分析查询语句,优化器将生成执行计划,执行器将执行查询并返回结果。存储引擎:存储引擎是 MySQL 的底层数据存储和检索系统。MySQL 支持多种存储引擎,包括 MyISAM、InnoDB、MEMORY 等。每种存储引擎都有其独特的特点和适用场景。例如,MyISAM 适用于静态数据,InnoDB 适用于高并发性能。MySQL 服务器的连接管理器负责管理客户端与服务器的连接。当客户端请求连接时,连接管理器会分配一个新的线程来处理该连接。连接管理器会监控连接的活动,当连接空闲时,会关闭它们,以释放服务器资源。存储引擎层的主要作用包括:数据的物理存储:存储引擎负责将数据存储在磁盘上,包括表的数据、索引等。数据的检索和处理:存储引擎负责将查询语句转换成对数据的检索操作,并对结果进行处理和排序等操作。事务处理:存储引擎负责实现 MySQL 的事务特性,包括事务的开始、提交和回滚等操作。并发控制:存储引擎负责实现并发控制机制,以保证多个用户同时访问数据库时的数据一致性和完整性。总的来说,MySQL 的架构采用了客户端 / 服务端模式,服务端包括多个组件,存储引擎提供底层数据存储和检索服务。这种架构的优点是可以提高 MySQL 的性能和可扩展性,同时使其更加灵活和可定制。五、SQL分类DDL【data definition language】 数据定义语言,用来维护存储数据的结构,代表指令: create, drop, alterDML【data manipulation language】 数据操纵语言,用来对数据进行操作,代表指令: insert,delete,updateDML中又单独分了一个DQL,数据查询语言,代表指令: selectDCL【Data Control Language】 数据控制语言,主要负责权限管理和事务,代表指令: grant,revoke,commit六、存储引擎存储引擎 是数据库管理系统如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。MySQL的核心就是插件式存储引擎,支持多种存储引擎。InnoDB 和 MyISAM 的对比事务支持:InnoDB 是支持事务的,而 MyISAM 不支持事务。锁机制:InnoDB 采用行级锁,而 MyISAM 采用表级锁。💕 查看存储引擎show engines;💕 存储引擎对比———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/m0_67595314/article/details/134231701
-
【话题交流】大家现在的项目都转高斯数据库了吗?随着国产xinchuang的推进,大多数国企进行国产化替代,你们的数据库都改为国产的了吗,用的高斯还是人大金仓还是达梦?
-
本月围绕数据库Mysql与 Redis与MongDB应用和理论,撰写了 多篇技术博客,内容涵盖原理讲解、部署实操、架构对比及高阶用法,适合有一定开发经验的同学系统性提升。具体内容如下:MongoDB Schema设计进阶https://bbs.huaweicloud.com/forum/thread-0242186151481963009-1-1.htmlRedis缓存三大经典问题:穿透、击穿、雪崩的防御体系与实践方案https://bbs.huaweicloud.com/forum/thread-0270186151287006008-1-1.htmlMySQL Online DDL演进https://bbs.huaweicloud.com/forum/thread-0270186149379800007-1-1.htmlMongoDB分片集群设计精要https://bbs.huaweicloud.com/forum/thread-0245186146589994004-1-1.htmlRedis Pipeline与事务https://bbs.huaweicloud.com/forum/thread-0270186139908337005-1-1.htmlGaussDB全局事务管理https://bbs.huaweicloud.com/forum/thread-0265186139485857004-1-1.htmlMySQL主从复制延迟:深度剖析与全方位优化指南https://bbs.huaweicloud.com/forum/thread-0270186139258938004-1-1.htmlMongoDB聚合框架https://bbs.huaweicloud.com/forum/thread-02111186137859433003-1-1.htmlRedis内存淘汰策略深度解析https://bbs.huaweicloud.com/forum/thread-0270186135899969003-1-1.html📌 本月技术内容聚焦 Redis、Mysql、MongDB,既有底层原理的讲解,也有实战落地的操作方案,欢迎阅读、收藏、转发,如有问题欢迎留言交流,下月见!🚀
-
Redis 数据库入门与实战教程在当今数据驱动的时代,高效的数据存储与读取至关重要。Redis 作为一款基于内存的高性能键值数据库,凭借其出色的读写速度、丰富的数据结构和高扩展性,在互联网技术栈中占据了重要地位。无论是缓存数据以减轻后端压力,还是实现实时计数器、消息队列,Redis 都能游刃有余。接下来,我们将深入探索 Redis 的世界,从基础到实战,全面掌握这一强大工具。一、Redis 基础概念Redis(Remote Dictionary Server),即远程字典服务,它将数据存储在内存中,支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。与传统的关系型数据库不同,Redis 采用键值对的存储方式,这使得数据的读写操作极为快速。由于数据常驻内存,Redis 的读写速度能够达到每秒数万次甚至更高,这也是它被广泛用于缓存场景的重要原因。此外,Redis 还具备持久化功能,通过 RDB(Redis Database)和 AOF(Append Only File)两种方式,将内存中的数据定期或实时写入磁盘,保证数据在断电等异常情况下不丢失,兼顾了速度与数据安全性。二、Redis 的安装与启动2.1 在 Linux 系统上安装 Redis下载 Redis:在终端中使用wget命令下载 Redis 的稳定版本,例如:wget http://download.redis.io/releases/redis-6.2.6.tar.gz解压文件:使用tar命令解压下载的压缩包:tar xzf redis-6.2.6.tar.gz编译安装:进入解压后的目录,执行编译和安装命令:cd redis-6.2.6 make make install启动 Redis:默认情况下,Redis 的配置文件位于redis-6.2.6/src目录下。可以使用以下命令启动 Redis 服务器:redis-server /path/to/redis.conf2.2 在 Windows 系统上安装 Redis下载 Redis:从 Redis 官方网站或 GitHub 上下载适用于 Windows 的 Redis 安装包。安装与配置:运行安装程序,按照提示完成安装。安装完成后,可以在安装目录下找到redis.windows.conf配置文件,根据需求进行配置。启动 Redis:在命令提示符中进入 Redis 安装目录,执行以下命令启动 Redis 服务器:redis-server.exe redis.windows.conf三、Redis 的数据结构与操作3.1 字符串(String)字符串是 Redis 最基本的数据结构,它可以存储字符串、整数或浮点数。例如,我们可以使用SET命令设置一个键值对,使用GET命令获取对应的值:SET mykey "Hello, Redis!" GET mykey此外,Redis 还提供了INCR(自增)、DECR(自减)等命令,方便对整数类型的值进行操作,这在实现计数器等场景中非常实用:SET count 0 INCR count GET count3.2 哈希(Hash)哈希用于存储字段和值的映射表,适合存储对象类型的数据。例如,我们可以使用HSET命令设置哈希字段的值,使用HGET命令获取对应字段的值:HSET user:1 name "John" age 30 city "New York" HGET user:1 name HGETALL user:1 3.3 列表(List)列表是一个双向链表,可以在头部或尾部插入元素。常用于实现消息队列、排行榜等功能。例如,使用LPUSH命令在列表头部插入元素,使用RPUSH命令在列表尾部插入元素,使用LRANGE命令获取列表指定范围内的元素:LPUSH mylist "apple" RPUSH mylist "banana" LRANGE mylist 0 -1 3.4 集合(Set)集合是一个无序且唯一的元素集合,适合用于去重、交集、并集等操作。例如,使用SADD命令向集合中添加元素,使用SMEMBERS命令获取集合中的所有元素:SADD myset "red" "green" "blue" SMEMBERS myset3.5 有序集合(Sorted Set)有序集合与集合类似,但每个元素都关联一个分数(score),集合中的元素根据分数进行排序。常用于实现排行榜等场景。例如,使用ZADD命令向有序集合中添加元素和分数,使用ZRANGE命令获取指定范围内的元素:ZADD scores 85 "Alice" 90 "Bob" 78 "Charlie" ZRANGE scores 0 -1 WITHSCORES 四、Redis 的高级应用4.1 缓存缓存是 Redis 最常见的应用场景之一。在 Web 应用中,我们可以将数据库中查询频率较高的数据缓存到 Redis 中,当再次请求相同数据时,直接从 Redis 中获取,避免重复查询数据库,从而提高系统的响应速度。例如,在 Java 应用中,可以使用 Jedis 等 Redis 客户端库实现缓存功能:import redis.clients.jedis.Jedis; public class RedisCacheExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost", 6379); // 从数据库中查询数据(假设这里有一个模拟的查询方法) String dataFromDB = getFromDatabase(); // 将数据缓存到Redis中,设置过期时间为60秒 jedis.setex("cached_data", 60, dataFromDB); // 从Redis中获取缓存数据 String cachedData = jedis.get("cached_data"); System.out.println(cachedData); jedis.close(); } private static String getFromDatabase() { // 模拟从数据库查询数据 return "Some data from database"; } } 4.2 消息队列Redis 的列表数据结构可以很方便地实现简单的消息队列。生产者将消息通过RPUSH命令写入列表,消费者使用LPOP命令从列表中读取消息,从而实现消息的异步处理。例如,在 Python 应用中,可以使用redis-py库实现消息队列:import redis r = redis.Redis(host='localhost', port=6379, db=0) # 生产者发送消息 r.rpush('message_queue', 'Hello, message 1') r.rpush('message_queue', 'Hello, message 2') # 消费者接收消息 message = r.lpop('message_queue') while message: print(message.decode('utf-8')) message = r.lpop('message_queue') 五、Redis 的集群与高可用随着业务的增长,单个 Redis 实例可能无法满足性能和数据存储的需求,这时就需要使用 Redis 集群。Redis 集群通过将数据分散存储在多个节点上,实现数据的分片和高可用性。常见的 Redis 集群方案有 Redis Cluster 和哨兵(Sentinel)模式。Redis Cluster 是 Redis 官方提供的分布式解决方案,它将数据划分为 16384 个槽(slot),每个节点负责一部分槽,客户端通过哈希算法计算键对应的槽,从而定位到存储该键的节点。哨兵模式则主要用于实现 Redis 的高可用性,它通过监控 Redis 主节点和从节点的状态,当主节点发生故障时,自动将从节点提升为主节点,保证服务的连续性。总结通过本文的学习,我们对 Redis 数据库有了全面的了解,从基础概念、安装配置,到各种数据结构的操作,再到缓存、消息队列等高级应用,以及集群与高可用方案。Redis 的强大功能和广泛应用使其成为现代开发中不可或缺的工具。在实际项目中,我们可以根据具体需求灵活运用 Redis,提升系统的性能和稳定性。随着技术的不断发展,Redis 也在持续更新和优化,未来还将有更多新特性和应用场景等待我们去探索和实践。
-
在数据驱动的时代,数据库管理系统(DBMS)是每个开发者和数据工程师都需要掌握的核心技能之一。其中,PostgreSQL(简称 PG)以其强大的功能、高度的可靠性和出色的扩展性,成为了开源数据库领域的佼佼者。无论是构建小型 Web 应用,还是支撑大型企业级系统,PG 都能提供稳定且高效的数据存储和管理服务。如果你正准备踏入 PG 的世界,这篇入门教程将带你从零开始,快速掌握 PG 数据库的基础知识和常用操作。一、认识 PostgreSQLPostgreSQL 起源于加州大学伯克利分校的 Ingres 项目,自 1986 年发布以来,经过数十年的发展,已经成为最先进的开源关系型数据库之一。它支持几乎所有的 SQL 标准,并在此基础上扩展了许多高级特性,如复杂查询、外键约束、触发器、视图、事务完整性、多版本并发控制(MVCC)等。同时,PG 还支持多种数据类型,包括几何数据、JSON、XML 等,能够满足不同场景下的数据存储需求。此外,它还具备良好的跨平台性,可在 Linux、Windows、macOS 等操作系统上运行。二、安装 PostgreSQL1. Windows 系统访问 PostgreSQL 官方网站(https://www.postgresql.org/download/windows/),下载对应版本的安装程序。运行安装程序后,按照向导提示进行操作,在安装过程中,你需要设置数据库超级用户(postgres)的密码,这个密码在后续管理数据库时会用到。安装完成后,PostgreSQL 会自动在系统中注册服务,并在开始菜单中创建相关快捷方式。2. macOS 系统可以使用 Homebrew 包管理器进行安装。打开终端,执行以下命令:brew install postgresql安装完成后,使用以下命令启动并设置开机自启:brew services start postgresql3. Linux 系统(以 Ubuntu 为例)在终端中执行以下命令添加 PostgreSQL 官方源:sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - 更新软件源并安装 PostgreSQL:sudo apt update sudo apt install postgresql安装完成后,PostgreSQL 服务会自动启动。三、连接到 PostgreSQL 数据库1. 使用命令行工具安装 PostgreSQL 时,会附带一个名为psql的命令行客户端。在 Windows 系统中,可以通过开始菜单找到SQL Shell (psql)并打开;在 Linux 和 macOS 系统中,直接在终端中输入psql -U postgres(postgres是默认的超级用户名),然后输入安装时设置的密码,即可连接到数据库。连接成功后,你会看到类似postgres=#的命令提示符。2. 使用图形化工具除了命令行,也可以使用图形化工具来管理 PG 数据库,如 pgAdmin、DBeaver 等。以 pgAdmin 为例,安装并打开 pgAdmin 后,通过 “添加新服务器” 向导,输入服务器名称、主机地址、端口号(默认 5432)、用户名和密码,即可建立连接。图形化工具提供了更直观的操作界面,方便进行数据库管理和 SQL 查询。四、基本数据库操作1. 创建数据库使用CREATE DATABASE语句创建一个新的数据库。例如,创建一个名为mydb的数据库:CREATE DATABASE mydb; 如果是在psql命令行中执行,记得在语句末尾加上分号;,然后按下回车键。2. 切换数据库在psql中,使用\c命令切换到指定数据库。例如,切换到刚刚创建的mydb数据库:\c mydb切换成功后,命令提示符会变为mydb=#。3. 创建表在数据库中创建表需要定义表的结构,包括列名、数据类型和约束条件。例如,创建一个名为users的表,用于存储用户信息:CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE, password VARCHAR(255) NOT NULL ); 上述语句中,SERIAL是一种自增整数类型,用于生成唯一的主键;VARCHAR用于存储可变长度的字符串;NOT NULL表示该列不能为空;UNIQUE表示该列的值必须唯一。4. 插入数据使用INSERT INTO语句向表中插入数据。例如,向users表中插入一条用户记录:INSERT INTO users (username, email, password) VALUES ('john_doe', 'johndoe@example.com', 'password123'); 如果要插入多条记录,可以使用逗号分隔多个VALUES子句:INSERT INTO users (username, email, password) VALUES ('Jane Smith', 'janesmith@example.com', 'pass456'), ('Bob Johnson', 'bobjohnson@example.com', 'abc789'); 5. 查询数据使用SELECT语句从表中查询数据。例如,查询users表中的所有记录:SELECT * FROM users; 如果只需要查询特定的列,可以列出列名,如:SELECT username, email FROM users; 还可以使用WHERE子句进行条件查询,例如,查询用户名是john_doe的用户:SELECT * FROM users WHERE username = 'john_doe'; 6. 更新数据使用UPDATE语句更新表中的数据。例如,将用户john_doe的密码更新为newpassword:UPDATE users SET password = 'newpassword' WHERE username = 'john_doe'; 7. 删除数据使用DELETE FROM语句删除表中的数据。例如,删除用户Bob Johnson的记录:DELETE FROM users WHERE username = 'Bob Johnson'; 五、进阶功能与实践1. 事务处理事务是一组操作的集合,要么全部成功执行,要么全部失败回滚,以保证数据的一致性和完整性。在 PG 中,可以使用BEGIN、COMMIT和ROLLBACK语句来管理事务。例如:BEGIN; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; COMMIT; 如果在执行过程中出现错误,可以使用ROLLBACK语句回滚所有操作。2. 索引优化索引可以加快数据查询的速度。通过CREATE INDEX语句创建索引。例如,为users表的email列创建索引:CREATE INDEX idx_email ON users (email); 合理创建索引可以显著提高查询性能,但过多的索引也会增加数据插入、更新和删除的开销,因此需要根据实际需求进行权衡。3. 备份与恢复PG 提供了多种备份和恢复数据的方法,如使用pg_dump命令进行逻辑备份,使用pg_basebackup命令进行物理备份。例如,使用pg_dump备份mydb数据库:pg_dump -U postgres mydb > mydb_backup.sql恢复备份时,可以使用psql命令将备份文件中的数据导入到数据库中:psql -U postgres mydb < mydb_backup.sql
-
数据库中的种子机与 BCV:数据管理的左右护法在数据库的庞大体系中,有两个概念虽不常被大众提及,却在数据管理的各个环节默默发挥着关键作用,它们就是种子机(Seed Machine)和 BCV(Branch and Catch Version,分支与捕获版本)。接下来,我们就深入探究一下这两位 “数据管理卫士”。种子机:数据世界的播种者种子机,从名字就能看出它的核心功能 —— 像播种一样为数据库注入初始数据。在数据库搭建完成后,往往需要填充大量基础数据用于后续的开发测试、系统演示等工作。这时候,种子机就派上用场了,它可以按照预先设定的规则,自动生成符合数据库表结构的模拟数据。比如在开发一个电商系统时,开发人员需要测试商品展示、订单处理等功能,就需要在数据库中创建商品表、用户表等,并填充大量模拟数据。通过编写种子机脚本,结合编程语言和数据库操作库,能快速生成包含商品名称、价格、用户姓名、地址等字段的模拟数据。以 Python 和 MySQL 为例,利用Faker库生成虚拟数据,再通过pymysql将数据插入到对应的表中,短短几分钟就能生成成千上万条测试数据,极大地提高了开发测试效率。除了软件开发场景,在数据仓库建设初期,种子机也用于初始化维度表和事实表,为后续的数据分析提供基础数据支撑。无论是模拟真实业务场景,还是构建数据模型,种子机都能高效地完成数据播种任务。BCV:数据版本的守护者BCV,即分支与捕获版本,主要用于数据版本管理和恢复。在数据库运行过程中,数据会随着业务操作不断变化,而有时我们需要保存数据在特定时间点的状态,以便在出现误操作、数据损坏等问题时能够快速恢复到之前的版本,BCV 就是实现这一目标的有效手段。从技术实现角度,不同数据库对 BCV 的支持方式有所不同。以 Oracle 数据库为例,它的闪回(Flashback)技术可以创建数据的时间点快照,这就是一种 BCV 实现。通过闪回查询,能够查询到过去某个时间点的数据;利用闪回表功能,还可以将表恢复到指定的历史状态。在分布式数据库中,通常会采用分布式快照算法,在多个节点上同时捕获数据版本,确保数据一致性的同时实现版本管理。BCV 在实际应用中有两大核心价值。一方面,当发生数据误删除、误修改等人为错误时,借助 BCV 可以快速找回丢失或错误修改的数据,将数据库恢复到正常状态,减少数据损失和业务中断时间。另一方面,在数据分析场景下,BCV 能帮助分析师获取不同时间点的数据版本,通过对比分析数据的变化趋势,挖掘数据背后的价值,为企业决策提供有力支持。二者协同:打造数据管理闭环种子机和 BCV 虽然功能各异,但在数据库管理中却相互配合,形成了一个完整的数据管理闭环。种子机生成的初始数据是数据库后续操作的基础,BCV 则从数据产生变化的那一刻起,开始守护数据的每一个版本。在数据恢复场景中,二者的协同作用尤为明显。如果因为数据错误需要重新初始化数据库,种子机可以重新生成数据,而 BCV 提供的错误发生前的数据版本则能作为参考,确保新生成的数据更贴合实际需求。在数据迁移和升级过程中,种子机负责生成新环境的测试数据,BCV 则保障迁移过程中数据的完整性和可恢复性,为数据的平稳过渡保驾护航。种子机和 BCV 就像是数据库管理中的左右护法,一个负责开疆拓土,为数据库注入生命;一个负责守护后方,保障数据安全可靠。理解并合理运用这两个概念,能让我们在数据库管理和开发工作中更加得心应手,充分发挥数据库的价值,为各类业务系统提供坚实的数据支持。
-
在 MySQL 数据库的运行过程中,my.ini(Windows 系统)或my.cnf(Linux 系统)配置文件起着关键作用,它决定了数据库的性能、存储、安全等多方面的行为。下面这篇博客将详细解析my.ini中核心参数的功能、配置建议,帮助你更好地管理和优化 MySQL 数据库。MySQL 数据库 my.ini 配置文件深度解析:性能优化与参数调优指南在 MySQL 数据库的世界里,my.ini(Windows 系统)或my.cnf(Linux 系统)就像是数据库的 “中枢神经”,它的每一项配置都直接影响着数据库的性能、稳定性和安全性。无论是新手 DBA 还是经验丰富的开发者,深入理解my.ini的配置参数,都是优化 MySQL 性能的必经之路。本文将带你逐一剖析my.ini的核心配置项,提供实战级的优化建议。一、my.ini 文件的基本结构与作用my.ini采用INI格式,通过[section]划分不同功能模块,常见的有[mysqld](核心服务配置)、[client](客户端连接配置)、[mysql](命令行客户端配置)等。核心作用包括:性能调优:调整内存分配、缓存大小、线程池等参数。存储管理:设置数据文件路径、日志存储策略。安全配置:限制访问权限、启用加密功能。复制与集群:配置主从复制、分布式集群参数。二、核心配置项深度解析2.1 [mysqld] 核心服务配置2.1.1 基础参数server-id:服务器唯一标识(用于主从复制),如server-id=1。port:监听端口,默认3306,可修改为port=3307以避免冲突。socket:Unix 系统下的套接字文件路径,Windows 系统无需配置。2.1.2 内存与缓存参数innodb_buffer_pool_size:InnoDB 存储引擎的缓冲池大小,建议设置为服务器物理内存的 50%-75%,如innodb_buffer_pool_size=8G。作用:缓存数据和索引,提升查询性能。调优:大内存服务器可设置多个缓冲池实例(innodb_buffer_pool_instances)。key_buffer_size:MyISAM 存储引擎的索引缓存,默认较小,MyISAM 表较多时需增大,如key_buffer_size=256M。query_cache_type:查询缓存开关(0 = 关闭,1 = 按需开启,2 = 强制开启),MySQL 8.0 已弃用,建议设置为0。2.1.3 日志参数log-bin:启用二进制日志(Binlog),记录所有写操作,用于主从复制和数据恢复,如log-bin=mysql-bin。expire_logs_days:Binlog 日志过期天数,默认0(不自动删除),建议设置为7,如expire_logs_days=7。slow_query_log:慢查询日志开关,用于定位性能瓶颈,如slow_query_log=1。long_query_time:慢查询阈值(秒),默认10,可调整为long_query_time=2。2.1.4 存储引擎参数default_storage_engine:默认存储引擎,建议设置为InnoDB(支持事务、外键),如default_storage_engine=InnoDB。innodb_file_per_table:为每个表单独创建.ibd文件(否则所有表共享系统表空间),建议开启,如innodb_file_per_table=1。2.2 [client] 客户端连接配置port:客户端默认连接端口,需与[mysqld]中的port一致。default-character-set:客户端默认字符集,建议设置为utf8mb4以支持 Emoji 等特殊字符,如default-character-set=utf8mb4。2.3 [mysql] 命令行客户端配置default-character-set:命令行客户端字符集,与[client]保持一致。三、性能优化实战案例3.1 高并发场景优化配置项调整:ini[mysqld] innodb_buffer_pool_size=16G innodb_buffer_pool_instances=8 innodb_io_capacity=2000 # 调整磁盘I/O能力 max_connections=500 # 最大连接数效果:缓存命中率提升至 95%,QPS 提高 30%。3.2 主从复制配置主库配置:ini[mysqld] server-id=1 log-bin=mysql-bin binlog_format=ROW # 基于行的复制模式从库配置:ini[mysqld] server-id=2 relay-log=mysql-relay-bin四、常见问题与解决方案问题现象可能原因解决方案MySQL 无法启动参数配置错误(如内存超限)恢复默认配置,逐步调整关键参数查询性能缓慢缓存不足、索引缺失增大innodb_buffer_pool_size,优化 SQL 语句磁盘空间不足Binlog 日志未清理设置expire_logs_days或手动清理日志文件乱码问题字符集不匹配统一设置default-character-set=utf8mb4五、最佳实践与安全建议备份与恢复:定期备份数据,并保留 Binlog 日志用于 Point-In-Time Recovery。安全加固:禁用匿名用户:user=root@localhost启用 SSL 加密:require_secure_transport=ON监控与调优:使用SHOW VARIABLES查看当前配置通过SHOW ENGINE INNODB STATUS分析 InnoDB 性能六、总结my.ini配置文件是 MySQL 性能优化的核心,每一个参数的调整都需要结合业务场景和服务器资源进行权衡。通过合理配置内存、缓存、日志等关键参数,不仅能提升数据库的响应速度,还能增强系统的稳定性和安全性。建议在修改配置后,先在测试环境验证效果,再逐步应用到生产环境。
-
MySQL 数据库两主两从结构:架构剖析、搭建实战与应用场景解析在追求高可用性与高性能的数据库架构设计中,MySQL 的两主两从结构凭借其独特的优势,成为许多企业的选择。这种架构不仅能提升读写性能,还增强了系统的容灾能力。本文将深入分析两主两从结构的原理、搭建过程及应用场景,助您全面掌握这一架构的核心要点。一、两主两从架构概述1.1 架构定义与组成MySQL 两主两从结构包含两个主库(Master)和两个从库(Slave)。两个主库之间通过双主复制(Mutual Replication)实现数据双向同步,每个主库分别对应一个从库,从库通过单向复制同步主库数据。其结构如下图所示:图片代码1.2 核心优势高可用性:当一个主库故障时,可快速切换至另一个主库,减少业务中断时间。负载均衡:读写操作可分散到不同节点,提升系统吞吐量。数据冗余:多副本存储数据,保障数据安全,降低丢失风险。1.3 适用场景高并发读写场景:如电商平台的商品详情页(读)与订单提交(写)。异地多活架构:两个主库部署在不同地域,实现就近读写。容灾备份:通过双主复制与从库同步,构建多层数据保护体系。二、两主两从架构原理分析2.1 双主复制机制双主复制基于 MySQL 的二进制日志(Binlog)实现双向同步:主库 A 写入数据:操作记录到 Binlog。主库 B 接收日志:通过I/O线程拉取 Binlog,并写入中继日志(Relay Log)。主库 B 重放日志:SQL线程执行中继日志,更新本地数据。反向同步:主库 B 的写操作以同样流程同步回主库 A。2.2 主从复制原理从库与主库的单向复制和传统主从架构一致:从库请求日志:从库I/O线程连接主库,获取 Binlog。写入中继日志:将 Binlog 写入本地中继日志。执行日志操作:SQL线程执行中继日志,同步主库数据。三、两主两从架构搭建实战3.1 环境准备节点角色IP 地址MySQL 版本配置要点主库 1192.168.1.1008.0.30启用 Binlog,设置 server-id=1主库 2192.168.1.1018.0.30启用 Binlog,设置 server-id=2从库 1192.168.1.1028.0.30关联主库 1,设置 server-id=3从库 2192.168.1.1038.0.30关联主库 2,设置 server-id=43.2 主库配置(以主库 1 为例,主库 2 类似)修改配置文件:编辑/etc/my.cnfini[mysqld] server-id=1 log-bin=/var/log/mysql/mysql-bin.log binlog_format=ROW # 防止循环复制(重要!) auto_increment_offset=1 auto_increment_increment=2 重启 MySQL 服务bashsudo systemctl restart mysqld创建复制账号sqlCREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; 获取主库状态sqlSHOW MASTER STATUS; -- 记录File和Position值,供另一主库配置使用 3.3 配置双主复制在主库 2 上配置主库 1 的连接sqlCHANGE MASTER TO MASTER_HOST='192.168.1.100', MASTER_USER='repl_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', -- 替换为主库1的File值 MASTER_LOG_POS=1234; -- 替换为主库1的Position值 START SLAVE; 在主库 1 上配置主库 2 的连接(步骤同 1,修改 IP 和日志参数)检查双主复制状态sql-- 在主库1和主库2分别执行 SHOW SLAVE STATUS\G -- 确保Slave_IO_Running和Slave_SQL_Running均为Yes 3.4 配置从库以从库 1 为例(关联主库 1)sqlCHANGE MASTER TO MASTER_HOST='192.168.1.100', MASTER_USER='repl_user', MASTER_PASSWORD='password', MASTER_AUTO_POSITION=1; -- 基于GTID复制 START SLAVE; 从库 2 关联主库 2(步骤同 1,修改 IP)四、两主两从架构的挑战与应对策略4.1 数据冲突问题冲突原因:双主同时修改同一行数据,导致同步冲突。解决方案:业务层面规避:通过业务逻辑避免双主同时写同一数据(如分库分表)。使用唯一键:设置UNIQUE KEY或PRIMARY KEY,冲突时触发错误。自动解决工具:使用gh-ost等工具自动合并冲突数据。4.2 切换与管理复杂性挑战:故障切换时需同时处理双主和从库的状态。解决方案:自动化工具:部署 MHA(Master High Availability)或 Orchestrator 实现自动故障转移。定期演练:制定切换预案并定期演练,确保紧急情况下快速响应。4.3 性能瓶颈问题:双主复制可能导致网络和 CPU 资源消耗过高。优化措施:调整复制参数:如max_allowed_packet、slave_parallel_workers。读写分离:通过中间件(如 MyCat、ProxySQL)将读请求导向从库。五、应用案例与最佳实践5.1 电商平台应用架构设计:主库 1 负责订单写入,主库 2 负责商品信息更新。从库 1 处理商品详情页查询,从库 2 提供订单查询服务。收益:读写性能提升 40%,故障切换时间缩短至 30 秒内。5.2 最佳实践总结监控体系:使用 Prometheus+Grafana 监控主从延迟、Binlog 同步状态。备份策略:定期备份主库,并保留 Binlog 用于 Point-In-Time Recovery。版本一致性:确保所有节点 MySQL 版本一致,避免兼容性问题。
-
MySQL 主备切换全解析:原理、实战与生产级优化策略在企业级数据库架构中,主备切换是保障系统高可用性的核心操作。当主库出现故障或需要升级维护时,如何快速、安全地将业务流量切换至备库,是 DBA 必须掌握的关键技能。本文将深入探讨 MySQL 主备切换的核心原理、实战流程及生产环境中的优化策略。一、主备切换的核心概念与分类1.1 切换类型对比切换类型触发场景数据一致性风险业务中断时间主备切换计划内维护(如版本升级)低(可保证)分钟级主备 failover主库突发故障(如硬件损坏)高(可能丢失未同步数据)秒级至分钟级1.2 数据同步状态对切换的影响强同步(半同步复制):主库写操作需等待至少一个备库确认接收 Binlog 后才返回成功,切换安全性高。异步复制:主库写操作立即返回,备库异步同步 Binlog,切换可能导致数据丢失。二、手动主备切换实战指南2.1 环境准备已搭建基于 GTID(全局事务标识符)的 MySQL 主备集群确认主备数据一致:SHOW MASTER STATUS与SHOW SLAVE STATUS2.2 切换前检查清单bash# 1. 确认主备延迟 mysql -e "SHOW SLAVE STATUS\G" | grep -E 'Seconds_Behind_Master|Last_Errno' # 2. 检查GTID一致性 mysql -e "SELECT @@GLOBAL.GTID_EXECUTED;" # 主备结果应相同 # 3. 锁定主库(仅适用于计划内切换) mysql -e "FLUSH TABLES WITH READ LOCK;" # 禁止写操作 mysql -e "SHOW OPEN TABLES WHERE In_use > 0;" # 确认无活跃事务 2.3 切换流程详解步骤 1:提升备库为主库sql-- 在备库上执行 STOP SLAVE; RESET SLAVE ALL; -- 清除复制配置 -- 启用Binlog(若未启用) SET GLOBAL log_bin = ON; SET GLOBAL server_id = 新ID; -- 与原主库不同 -- 确认当前GTID位置 SHOW MASTER STATUS; 步骤 2:配置应用连接新主库修改应用配置文件,指向新主库 IP / 端口执行应用滚动重启,验证连接正常步骤 3:将原主库加入集群作为新备库sql-- 在原主库上执行(假设已恢复服务) RESET MASTER; CHANGE MASTER TO MASTER_HOST='新主库IP', MASTER_USER='repl_user', MASTER_PASSWORD='password', MASTER_AUTO_POSITION=1; -- 基于GTID复制 START SLAVE; 步骤 4:验证集群状态sql-- 在新备库(原主库)上检查同步状态 SHOW SLAVE STATUS\G -- 确保Slave_IO_Running和Slave_SQL_Running均为Yes 三、自动 Failover 实现方案3.1 基于 MHA 的自动切换MHA(Master High Availability)是 MySQL 官方推荐的高可用解决方案,核心优势:自动检测主库故障(基于 SSH 心跳)智能选择最优备库提升为主库自动修复复制拓扑,保持集群完整性部署要点:安装 MHA Manager 节点配置 SSH 免密登录创建故障切换脚本:bash# master_failover_script.sh #!/bin/bash # 包含VIP切换、应用通知等逻辑 3.2 基于 Keepalived 的 VIP 漂移通过虚拟 IP(VIP)实现客户端无感知切换:ini# Keepalived配置示例 vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.100 # VIP地址 } } 四、生产环境中的关键挑战与应对策略4.1 数据一致性保障策略:优先使用 GTID 复制启用半同步复制(rpl_semi_sync_master_enabled=ON)切换前执行FLUSH TABLES WITH READ LOCK锁定主库4.2 最小化业务中断预热连接池:切换前在新主库建立连接池应用层重试机制:封装数据库操作,支持自动重连分级切换:非核心业务优先切换,核心业务最后切换4.3 故障恢复演练季度演练计划:模拟主库硬件故障执行手动 failover恢复原主库并重新加入集群记录切换时间与问题点关键指标:平均恢复时间(MTTR)≤5 分钟数据丢失量≤0.1%五、主备切换的监控与预警体系5.1 核心监控指标监控项阈值设定预警级别主备延迟(Seconds_Behind_Master)>5 秒警告Binlog 写入速率>100MB / 秒严重复制 IO 线程状态非 Running紧急复制 SQL 线程状态非 Running紧急5.2 监控工具推荐Prometheus+Grafana:自定义监控面板,可视化复制状态pt-heartbeat:精确测量主备延迟(亚秒级)MySQL Enterprise Monitor:官方监控套件,提供复制健康检查六、总结与最佳实践技术选型:计划内切换:优先使用基于 GTID 的手动切换故障切换:部署 MHA+Keepalived 实现自动化操作规范:所有切换操作必须记录到变更管理系统切换前备份主库(至少导出 binlog 位置)切换后执行完整性校验(如核对关键业务数据)架构演进:对可用性要求极高的场景,考虑 MySQL Group Replication引入中间件(如 ProxySQL)实现连接层的智能路由
-
MySQL 数据库主备搭建指南:原理、实战与最佳实践在数字化浪潮下,数据库的稳定性与高可用性成为企业核心业务的基石。MySQL 作为最流行的开源关系型数据库之一,通过主备架构可有效保障数据安全、提升系统容灾能力。本文将从原理剖析到实战操作,带您全面掌握 MySQL 主备搭建的核心技术。一、为什么需要 MySQL 主备架构?1.1 核心价值数据冗余:主库数据实时同步至备库,防止单点故障导致数据丢失。读写分离:主库负责写操作,备库承担读请求,缓解主库压力,提升系统吞吐量。高可用性:主库故障时,备库可快速切换为主库,减少业务中断时间。1.2 应用场景电商交易系统:主库处理订单写入,备库支持商品详情页查询。金融系统:备库作为灾备节点,确保交易数据安全。日志分析:备库存储历史数据,供离线分析使用。二、MySQL 主备复制原理详解MySQL 主备复制基于 ** 二进制日志(Binlog)** 实现,核心流程分为三步:主库记录 Binlog:主库将所有写操作(如INSERT、UPDATE、DELETE)记录到 Binlog 中。备库请求 Binlog:备库通过I/O线程连接主库,请求最新的 Binlog 日志。备库重放日志:备库的SQL线程接收 Binlog,并在本地执行,实现数据同步。关键参数解析server-id:每个 MySQL 实例的唯一标识(主备需不同)。log-bin:启用 Binlog 日志,并指定存储路径。relay-log:备库用于存储从主库接收的 Binlog 日志。三、实战:基于 CentOS 的 MySQL 主备搭建3.1 环境准备角色IP 地址系统版本MySQL 版本主库192.168.1.100CentOS 78.0.30备库192.168.1.101CentOS 78.0.303.2 主库配置修改配置文件:编辑/etc/my.cnf[mysqld] server-id=1 log-bin=/var/log/mysql/mysql-bin.log binlog_format=ROW 重启 MySQL 服务sudo systemctl restart mysqld创建复制账号CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; 获取主库状态SHOW MASTER STATUS; -- 记录File和Position值,后续备库配置使用 3.3 备库配置修改配置文件:编辑/etc/my.cnf[mysqld] server-id=2 relay-log=/var/log/mysql/mysql-relay-bin.log重启 MySQL 服务sudo systemctl restart mysqld配置主库连接CHANGE MASTER TO MASTER_HOST='192.168.1.100', MASTER_USER='repl_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', -- 替换为主库的File值 MASTER_LOG_POS=1234; -- 替换为主库的Position值 START SLAVE; 检查同步状态SHOW SLAVE STATUS\G -- 确保Slave_IO_Running和Slave_SQL_Running均为Yes 四、主备切换与高可用优化4.1 手动主备切换提升备库为主库STOP SLAVE; RESET SLAVE ALL; RESET MASTER; 将原主库配置为新备库(操作同 3.3 节)4.2 高可用工具推荐MHA(Master High Availability):自动检测主库故障并完成切换,支持多节点集群。Orchestrator:基于 Go 语言开发,可视化管理 MySQL 集群,提供故障预警与自动修复。Keepalived+VIP:通过虚拟 IP 实现主备切换,简化客户端连接配置。五、常见问题与解决方案问题现象可能原因解决方法备库同步延迟过大Binlog 传输或 SQL 执行缓慢优化 SQL 语句、调整 I/O 线程参数、增加备库资源主备数据不一致手动修改备库数据停止同步,从主库重新初始化备库SHOW SLAVE STATUS显示异常账号权限不足或配置错误检查账号权限、核对主备配置参数六、总结与最佳实践定期监控:使用pt-heartbeat等工具实时监测主备延迟。备份策略:结合mysqldump与 Binlog 实现增量备份,确保数据可恢复。安全加固:限制复制账号权限,启用 SSL 加密传输 Binlog。通过搭建 MySQL 主备架构,企业可显著提升数据库的可用性与性能。在实际应用中,需根据业务需求选择合适的高可用方案,并持续优化配置,以应对日益增长的数据挑战。
-
dynamic-datasource detect druid publicKey,It is highly recommended that you use the built-in encryption method使用druid-spring-boot-starter 1.2.11作为数据库连接池 + dynamic-datasource-spring-boot-starter 3.4.1作为多数据源支持,并且使用了druid的数据库密钥加密功能,启动项目发现日志中有如下日志:[2024-10-31 15:42:55.343] - [INFO ] - [15336] - [240E04791E60243BB7BE00FEE00CC8F33BE822D8CFE09DDE00D10000] - [main] - [c.b.d.d.s.b.a.d.DruidConfig-255] - dynamic-datasource detect druid publicKey,It is highly recommended that you use the built-in encryption method https://dynamic-datasource.com/guide/advance/Encode.htmlyml中数据源的配置信息为:spring: datasource: # 多数据源配置 dynamic: primary: db1 strict: true datasource: # 第一个数据源 db1: url: jdbc:mysql://localhost:3306/db1?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 # 公钥 public-key: xxx # 第二个数据源 db2: url: jdbc:mysql://localhost:3306/db2?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 # 公钥 public-key: xxx根据日志在com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidConfig类中定位到了日志输出位置,这个类是druid数据库连接池的配置类,Properties connectProperties = connectionProperties == null ? g.getConnectionProperties() : connectionProperties;if (publicKey != null && publicKey.length() > 0) { if (connectProperties == null) { connectProperties = new Properties(); } log.info("dynamic-datasource detect druid publicKey,It is highly recommended that you use the built-in encryption method \n " + "https://dynamic-datasource.com/guide/advance/Encode.html"); connectProperties.setProperty("config.decrypt", "true"); connectProperties.setProperty("config.decrypt.key", publicKey);}this.connectionProperties = connectProperties;发现如果druid的公钥配置在publicKey下就会触发日志输出,并且会设置两个配置属性到connectProperties中,一个是config.decrypt,一个是config.decrypt.key。修改yml中的配置,不在publicKey下配置公钥,而是配置到connectionProperties下:spring: datasource: # 多数据源配置 dynamic: primary: db1 strict: true datasource: # 第一个数据源 db1: url: jdbc:mysql://localhost:3306/db1?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 # 公钥 connection-properties: "config.decrypt": "true" "config.decrypt.key": xxx # 第二个数据源 db2: url: jdbc:mysql://localhost:3306/db2?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 # 公钥 connection-properties: "config.decrypt": "true" "config.decrypt.key": xxx启动项目发现数据库连接失败:Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)再次在DruidConfig类中查看publicKey使用到的位置,发现://filters单独处理,默认了stat,wallString filters = this.filters == null ? g.getFilters() : this.filters;if (filters == null) { filters = "stat";}if (publicKey != null && publicKey.length() > 0 && !filters.contains("config")) { filters += ",config";}properties.setProperty(FILTERS, filters);原来还需要设置druid的filters属性,修改yml中的配置为:spring: datasource: # 多数据源配置 dynamic: primary: db1 strict: true datasource: # 第一个数据源 db1: url: jdbc:mysql://localhost:3306/db1?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 filters: "stat,config" # 公钥 connection-properties: "config.decrypt": "true" "config.decrypt.key": xxx # 第二个数据源 db2: url: jdbc:mysql://localhost:3306/db2?... username: root password: xxx druid: ... min-evictable-idle-time-millis: 300000 max-evictable-idle-time-millis: 300000 filters: "stat,config" # 公钥 connection-properties: "config.decrypt": "true" "config.decrypt.key": xxx再次启动项目,成功启动且没有再出现dynamic-datasource detect druid publicKey,It is highly recommended that you use the built-in encryption method日志。转载自https://www.cnblogs.com/imadc/p/18517970
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签