10
2
1
0
专栏/.../

WordPress 使用 TiDB Cloud 替换 MySQL

 meathill  发表于  2023-04-20

白嫖使我快乐。一直白嫖,一直快乐,😊。感谢 TiDB,感谢 TiDB Cloud,你们让我的博客内容更丰富多彩。

前言

我这个博客从 2011 年开始写,如今已经 12 年。最早,从 ZOL 离职后,我需要换个新平台写博客;另一方面,我也想学习 Linux、PHP、MySQL,这些原本不熟悉的技术,于是选择了 WordPress。这么多年来,服务器从共享主机搬迁到 VPS,又升级到云主机;PHP 从 5.5、5.6 升级到 7,又升级到 8;Apache 被换成 Nginx;唯独数据库没有变化,基本一套老框架沿用至今。

我前阵子发现:因为编码问题,无法在标题里或正文里插入表情符号。于是升级数据库也被提上日程。刚好我一直关注的 TiDB 开始提供云数据库服务,采用 Serverless 模式,免费额度有 5GiB 可以用,足够我写博客。于是我就准备趁此机会切换到 TiDB Cloud 上。

注册 TiDB Cloud

打开 tidbcloud.com 注册即可。

TiDB Cloud 很大方,不需要绑卡,不需要繁琐的操作,直接第三方登录就可以使用。Serverless(Free Tier)只支持 AWS 机房,可选的位置也不多,因为我 ECS 买在美西,所以就把数据库也买在美西,这样速度应该会快一些。

每个账号可以建一个免费的 Serverless 数据库,只要稍稍点两下,就建好了,体验很流畅,这里不再赘述。接下来开始使用。

连接 TiDB Cloud

数据库准备就绪之后,我们可以进入数据库详情页。点击右上角的“Connect”按钮,即可打开连接信息窗口。

no-alt

TiDB 贴心的准备了各种客户端、各种平台的连接方式,对于我这种数据库准小白来说非常有帮助。第一次使用,需要点击右下角的“Reset password”按钮生成数据库密码,生成后,这个按钮会变成复制密码。记得要妥善保存密码,因为我们不能再次查看或者获取。

这里发现一个设计缺陷:点击 Reset password 按钮没有确认过程,所以我的数据库密码直接就被改掉了……这种破坏性操作还是应该多一个确认比较好,回头反馈给 TiDB 的工作人员。

导入数据

TiDB Cloud 只支持导入 CSV 文件,比较难用。可能因为我数据库知识储备不足,我甚至想象不出 CSV 该怎么支持表结构😅。不过没关系,我有 JetBrains 全家桶,命令行操作也还凑合,所以直接从本地跑就行。

首先在服务器上执行 mysqldump -u USER -p --database BLOG_DB > backup.sql 把整个博客数据库包含数据结构都导出到 backup.sql 文件里。

打开 sql 文件,把数据库的编码全部改成 utf8mb4 或者 utf8mb4_unicode_ci,这样就可以支持表情符号咯 🎉🎉。

打开 DataGrip,按照上一节介绍建立数据库连接,右键,选择“SQL Scripts”,然后执行刚才的 SQL,等一会儿,数据即可完成导入。当然,实际过程肯定没有这么顺利,不过云数据库嘛,有问题就直接整个节点干掉再重建就好。不留脏数据。

WordPress 连接

TiDB Cloud 要求必须使用 TLS 安全连接,所以我们需要修改 wp-config.php

/** WordPress数据库的名称 */
define('DB_NAME', 'blog');

/** MySQL数据库用户名 */
define('DB_USER', '用户名');

/** MySQL数据库密码 */
define('DB_PASSWORD', '密码');

/** MySQL主机 */
define('DB_HOST', '主机域名:端口');

/** 使用 SSL 连接 */
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

因为我的服务器是 Ubuntu 22.04 系统,证书放在默认位置,可以自动加载。如果你使用其它系统,可能需要修改一下证书路径。

解决 SQL_CALC_FOUND_ROWS导致翻页丢失的问题

完成上述操作,打开博客,500 😱。查看 error.log,原来是不支持 SQL_CALC_FOUND_ROWS 导致报错。我并不知道这个东西是干嘛用的,丢到 Google 里搜索,找到这个 issue,原来 WordPress 的 SQL 要使用这个函数,但是 TiDB 并不支持。

解决方案是在数据库里执行 SET GLOBAL tidb_enable_noop_functions=1。之后 WordPress 不会再报错,但是相应的,翻页功能也没有了,因为 WordPress 无法统计博文数量。

继续搜索。看起来 SQL_CALC_FOUND_ROWS 并不是什么好东西,不知道为什么 WordPress 至今都不愿意把它移除。还好,WP 留有开关,我们可以关闭这个函数的使用。我自己创建了一个 肉山的 WordPress 插件 ,用来给博客加广告、调整页面,所以我就在里面添加函数,关掉 SQL_CALC_FOUND_ROWS

if ( ! function_exists( 'wpartisan_set_no_found_rows' ) ) :
  function wpartisan_set_no_found_rows( \WP_Query $wp_query ) {
    $wp_query->set( 'no_found_rows', true );
  }
endif;
add_filter( 'pre_get_posts', 'wpartisan_set_no_found_rows', 10, 1 );

if ( ! function_exists( 'wpartisan_set_found_posts' ) ) :
  function wpartisan_set_found_posts( $clauses, \WP_Query $wp_query ) {
    // Don't proceed if it's a singular page.
    if ( $wp_query->is_singular()  ) {
      return $clauses;
    }

    global $wpdb;

    // Check if they're set.
    $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
    $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
    $distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';

    // Construct and run the query. Set the result as the 'found_posts'
    // param on the main query we want to run.
    $wp_query->found_posts = $wpdb->get_var( "SELECT $distinct COUNT(*) FROM {$wpdb->posts} $join WHERE 1=1 $where" );

    // Work out how many posts per page there should be.
    $posts_per_page = ( ! empty( $wp_query->query_vars['posts_per_page'] ) ? absint( $wp_query->query_vars['posts_per_page'] ) : absint( get_option( 'posts_per_page' ) ) );

    // Set the max_num_pages.
    $wp_query->max_num_pages = ceil( $wp_query->found_posts / $posts_per_page );

    // Return the $clauses so the main query can run.
    return $clauses;
  }
endif;
add_filter( 'posts_clauses', 'wpartisan_set_found_posts', 10, 2 );

调整完毕,翻页功能恢复正常。

使用体验小结

Serverless 讲究一个即用即起,平时是休眠状态,有人用才会启动。所以最好避免冷启动,否则第一个用的人要等很长时间,体验很差。作为博客,更简单的方式是配置 CDN,给首页外的页面添加长期缓存,就能改善大部分用户的体验。我目前使用着腾讯云 CDN,准备回头切回七牛。

实际上我目前使用了一个多月,并没有冷启动的感觉。我的博客日均几百的访问量,感觉相当可以。另外一个 Serverless 实例,作为 NoCoDB 的数据库,因为访问量很小,所以冷启动感觉很明显。

其它方面,速度和效率都不比本地数据库差,以后我再搞产品,应该都不会自己搭数据库了,嘿嘿嘿。

后记

我已经两次报名参加 TiDB Hackathon,第一次止步外围筛选第二次虽然进入决赛圈,可惜因为对云数据库不了解,挑战开发 NoCoDB+TiDB Cloud 失败,铩羽而归。

但是借用群里同学的说法:人生没有白走的路,每一步,都算数。虽然 Hackathon 没能获得好成绩,但是我获得了更多关于 TiDB Cloud 的知识,于是这次可以顺利完成迁移。

目前博客网站使用体验良好,速度不比之前使用本地数据库慢。前两天,我发现 TiDB Cloud 开放了 Data Service,提供 HTTP Endpoint,这表示着他们向 DaaS(Database as a Service)更近一步,也意味着我们在 Edge Function 里使用 TiDB Cloud 成为可能。那么接下来,我打算好好利用一下这个薅羊毛机会,把几个 Side Project 的数据端放在 TiDB Cloud 上,跟 Supabase 比一比,看哪个更好用,更适合新项目、小公司从零到一。

到时候也会写成更多文章,或许做成视频,跟大家分享。

如果各位读者老爷对数据库、云开发、薅羊毛感兴趣,欢迎留言讨论,可提出问题,亦可指点一二,均非常欢迎。

10
2
1
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论