0

0

Laravel如何实现数据库主从读写分离_Laravel配置多个数据库连接读写点【详解】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-05 11:38:02

|

500人浏览过

|

来源于php中文网

原创

Laravel主从读写分离需在database.php中将read/write配置为同一连接名的子键,读操作自动走从库仅限纯SELECT且未显式指定连接、非事务内;写操作、事务、显式连接等一律走主库。

laravel如何实现数据库主从读写分离_laravel配置多个数据库连接读写点【详解】

Laravel 原生支持主从读写分离,但不是“开箱即用”的自动路由,必须显式配置连接、指定读写意图,且需注意查询构造器与 Eloquent 的行为差异——否则所有查询仍走主库。

如何配置 database.php 中的主从连接组

Laravel 不是靠“添加两个独立连接”实现读写分离,而是把多个从库(read)和一个主库(write)归入同一个逻辑连接名下。关键在 'connections' 数组中使用 'read''write' 子键:

 'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'prefix_indexes' => true,
    'strict' => true,
    'engine' => null,
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        PDO::MYSQL_ATTR_SSL_CERT => env('MYSQL_ATTR_SSL_CERT'),
        PDO::MYSQL_ATTR_SSL_KEY => env('MYSQL_ATTR_SSL_KEY'),
    ]) : [],
    'read' => [
        'host' => [
            env('DB_READ_HOST_1', '192.168.1.10'),
            env('DB_READ_HOST_2', '192.168.1.11'),
        ],
    ],
    'write' => [
        'host' => env('DB_WRITE_HOST', '192.168.1.5'),
    ],
],
  • read.host 是数组,Laravel 会轮询选择其中一个从库(非负载均衡,无健康检查)
  • write.host 必须是单个字符串,不能是数组;写操作只发往此处
  • 所有其他连接参数(如 usernamepassworddatabase)若未在 read/write 内单独覆盖,则继承外层配置
  • 如果从库需要不同账号,必须在 read 下显式写出 'username''password'

哪些查询会自动走从库?哪些不会?

只有「纯读操作」且未显式指定连接时,Laravel 才可能路由到从库。但以下情况一律走主库:

  • 任何含 insert()update()delete()increment() 等写方法的查询构造器调用
  • Eloquent 模型调用 save()create()delete()update()
  • 事务内所有查询(即使只是 select),因为事务必须在单一连接上执行
  • 使用 DB::connection('mysql') 显式获取连接后,再调用 table()->get() —— 此时 Laravel 无法推断意图,强制走主库
  • DB::select()DB::statement() 等原生方法不参与读写分离,始终走默认连接(即主库)

真正能触发从库路由的是:DB::table('users')->where('id', 1)->first()User::find(1) 这类未包裹在事务、未显式绑定连接、且语法明确为只读的操作。

如何强制走主库或从库?

当自动路由不符合预期(比如刚写入就要立刻读取,避免从库延迟),必须手动指定连接:

Notion AI
Notion AI

Notion是一款集成了笔记、知识库、数据表格、看板、日历等多种能力于一体的应用程序,它既可供个人使用,也可以与他人进行跨平台协作。

下载
  • 强制走主库:DB::connection('mysql')->table('users')->first() —— 注意:这里传的是连接名 'mysql',不是 'mysql_write';Laravel 在该连接配置下会主动选 write 分支
  • 强制走从库:DB::connection('mysql')->usingConnection('read')->table('users')->first()(Laravel 9+);旧版本需用 DB::connection('mysql.read'),但该写法已被弃用且不稳定
  • Eloquent 中强制主库:User::on('mysql')->find(1);强制从库:User::on('mysql')->withWrite(false)->find(1)withWrite(false) 是 Laravel 8.34+ 引入的明确标记)

注意:on('mysql.read') 是错误写法,'mysql.read' 并不是一个真实连接名,只是配置里的嵌套结构。

常见踩坑点和验证方式

主从分离配置后没生效,大概率卡在这几个地方:

  • 环境变量未生效:检查 .envDB_READ_HOST_1 是否拼写正确,是否被 php artisan config:clear 清除缓存后重载
  • 从库权限不足:MySQL 账号需有 SELECT 权限,且 bind-address 允许远程连接;用 mysql -h 192.168.1.10 -u read_user -p 手动测试连通性
  • 忘记关闭 strict 模式导致从库报错:某些从库因复制延迟,执行 SELECT ... FOR UPDATE 会失败,而 Laravel 在某些场景下会隐式加锁
  • 没有验证实际走哪个库:在 DB::listen() 回调里打印 $event->connectionName$event->sql,或在数据库侧开启 general_log 查看请求来源 IP

最易被忽略的是:Eloquent 的 withCount()withSum() 等聚合关系方法,在关联模型未指定连接时,会回退到主库执行子查询——这意味着一次列表页可能混合走了主从,却不自知。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2206

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1463

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1368

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

951

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1411

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1233

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1443

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.6万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 780人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号