MySQL主从复制与读写分离

MySQL使用主从复制与读写分离的原因

1、在企业应用中,成熟的业务通常数据量都比较大
2、单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
(myisam基于表级锁定;innodb基于行级锁定 --存储引擎不能满足并发读、写的需求)
3、配置多台主从数据库服务器以实现读写分离

MySQL主从复制原理

MySQL的复制类型
基于语句的复制
基于行的复制
混合类型的复制(语句、行、日志文件)

复制的基本过程

  1. Master将用户对数据库更新的操作以二进制格式保存到Binary Log日志文件中

  2. Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
    IO进程:从数据库复制主数据库上二进制日志的进程

3.Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;

4.Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”

  1. Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行.
    Sql进程:将二进制日志内容翻译成SQL语句写进从数据库

MySQL读写分离原理

1、只在主服务器上写,只在从服务器上读
2、主数据库处理事务性查询,从数据库处理select查询
3、数据库复制用于将事务性查询的变更同步到集群中的从数据库
4、复制的基本过程如下:
Master将用户对数据库更新的操作以二进制格式保存到Binary Log日志文件中
Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容
Master接收来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置
Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清除的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”
SlaveSql进程检测到relay-log中新增了内容后,会马上解析relay-log的内容称为在Master端真实执行时候的那些可执行的内容,并在自身执行

项目

环境

mysql主数据:192.168.188.10
mysql从数据库:192.168.188.20 192.168.188.30
Amoeba:192.168.188.40
client:192.168.188.50

注:一定要关闭防火墙和核心防护

1、关闭防火墙和核心防护(所有设备)


[root@master ~]# systemctl stop firewalld
[root@master ~]# setenforce 0
setenforce: SELinux is disabled
[root@master ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config 
[root@master ~]# grep -v "#" /etc/selinux/config

SELINUX=disabled
SELINUXTYPE=targeted 

2、设备主从时间同步 (主数据库)


[root@master ~]# yum -y install ntpdate ntp   //安装ntp软件

[root@master ~]# ntpdate ntp.aliyun.com  //时间同步
29 Dec 08:59:36 ntpdate[15322]: adjust time server 203.107.6.88 offset -0.003530 sec

[root@master ~]# date  //查看当前时间
20201229日 星期二 09:00:58 CST
[root@master ~]# vim /etc/ntp.conf  

  8 restrict default nomodify    #定义默认访问规则,nomodify禁止远程主机修改本地服务器配置
 17 #restrict 192.168.188.0 mask 255.255.255.0 nomodify notrap   #从192.168.188.1192.168.188.254主机都可以设用ntp时间同步

 21 fudge 127.127.1.0 stratum 10  #时间同步为10级 ,是向其他服务器提供时间同步的同步源 ,最好不要设置022 server 127.127.1.0   #设置本机为同步源


[root@master ~]# systemctl restart ntpd   //重启ntp服务
[root@master ~]# netstat -anpu | grep ntpd   //查看ntp服务状态
udp        0      0 192.168.188.10:123      0.0.0.0:*                           15919/ntpd          



2、部署时间同步的任务计划(主数据库)
[root@master ~]# crontab -e
*/30 * * * * /usr/sbin/ntpdate ntp.aliyun.com   #每隔30秒跟阿里云时间同步




从数据库12上面安装
[root@slave1 ~]# yum -y install ntpdate   //安装ntp全歼
[root@slave1 ~]# ntpdate 192.168.188.10  //设置192.168.188.10为时间同步源
29 Dec 09:19:28 ntpdate[61580]: adjust time server 192.168.188.10 offset -0.006004 sec
[root@slave1 ~]# date   //查看当前时间
20201229日 星期二 09:19:46 CST

[root@slave1 ~]# crontab -e  //设置时间同步源
*/5 * * * * /usr/sbin/ntpdate 192.168.188.10   #每隔5分钟进行一次同步对象为192.168.188.10(主数据库)的时间同步

[root@slave1 ~]# date  //查看当前时间
20201229日 星期二 09:31:20 CST

3、配置主从复制(主数据库)

[root@master ~]# vim /etc/my.cnf
检索server-id = 1下面添加
log_bin=master_bin  #同步二进制日志前缀
log_slave_updates=true   #允许日志同步到从数据库

[root@master ~]# systemctl restart mysqld   //重启数据库服务
[root@master ~]# mysql -uroot -p123456  //登录数据库
mysql> grant replication slave on *.* to 'myslave'@'192.168.188.%' identified  by '123456';    //授权从数据库复制权限,可复制所有表所有库,
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;  //刷新授权
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;  //查看主数据库状态
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master_bin.000001 |      864 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

从数据库1上


[root@slave1 ~]# vim /etc/my.cnf
server-id = 2   #修改  服务id为2
relay_log=relay-log-bin    #二进制日志中继日志前缀
relay_log_index=slave-relay-bin-bin.index   #中继日志索引

在这里插入图片描述

[root@slave1 ~]# systemctl restart mysqld
[root@slave1 ~]# mysql -uroot -p123123
mysql> change master to master_host='192.168.188.10',master_user='myslave',master_password='123456',master_log_file='master_bin.000001',master_log_pos=864;   //设置主数据库的ip地址密码 日志文件
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;   //开启从状态
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G  //查看从数据库的状态信息

在这里插入图片描述

从数据库2上


[root@slave2 ~]# vi /etc/my.cnf
server-id = 3            # 服务id为2
relay_log=relay-log-bin   #二进制日志的中继日志前缀
relay_log_index=slave-relay-bin.index  #中继日志索引

[root@slave2 ~]# systemctl restart mysqld
[root@slave2 ~]# mysql -uroot -p123123

mysql> change master to master_host='192.168.188.10',master_user='myslave',master_password='123456',master_log_file='master_bin.000001',master_log_pos=864;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

mysql> start slave;   //开启从数据库
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G  //查看从数据库的状态
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.188.10
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master_bin.000001
          Read_Master_Log_Pos: 864
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master_bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

4、主从测试

主数据库上


mysql> show databases;  //查看所有库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| auth               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> create database song;  //创建一个song数据库
Query OK, 1 row affected (0.00 sec)

mysql> show databases;  //查看是否有song库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| auth               |
| mysql              |
| performance_schema |
| song               |
| sys                |
+--------------------+
7 rows in set (0.00 sec)

从数据库1上

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| song               |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

从数据库2上


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| song               |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

5、设置读写分离

因为ameoba用户授权给用户时默认的数据库为test
所以在主数据库时创建数据库test

主数据库

mysql> create database test;  //创建test数据库
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| auth               |
| mysql              |
| performance_schema |
| song               |
| sys                |
| test               |
+--------------------+
8 rows in set (0.00 sec)

在amoeba上

设置时间同步

[root@amoeba ~]# yum -y install ntpdate 
[root@amoeba ~]# ntpdate 192.168.188.10
29 Dec 10:19:44 ntpdate[43430]: adjust time server 192.168.188.10 offset -0.071035 sec
[root@amoeba ~]# crontab -e 
*/5 * * * * /usr/sbin/ntpdate 192.168.188.10

添加jdk-8u91-linux-x64.tar.gz

[root@amoeba ~]# tar zxvf jdk-8u91-linux-x64.tar.gz

在这里插入图片描述

[root@amoeba ~]# cp -rv jdk1.8.0_91/ /usr/local/java   //-rv 递归显示进程	
[root@amoeba ~]# vim /etc/profile
export JAVA_HOME=/usr/local/java   # 设置JAVA根目录为全局变量
export JRE_HOME=/usr/local/java/jre
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin  #环境变量,在PATH环境变量中添加JAVA根目录下bin子目录
export CLASSPATH=./:$JAVA_HOME/lib:$JRE_HOME/lib   #类路径

[root@amoeba ~]# source /etc/profile
[root@amoeba ~]# echo $PATH    //输出变量
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/java/bin:/usr/local/java/jre/bin:/usr/local/java/bin:/usr/local/java/jre/bin
[root@amoeba ~]# echo $CLASSPATH      //输出类路径信息
./:/usr/local/java/lib:/usr/local/java/jre/lib
[root@amoeba ~]# java -version    //查看版本
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)

安装管理软件
添加 amoeba-mysql-3.0.5-RC-distribution.zip

在这里插入图片描述


[root@amoeba ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip
[root@amoeba ~]# mv amoeba-mysql-3.0.5-RC/ /usr/local/amoeba
[root@amoeba ~]# chmod -R 755 /usr/local/amoeba   //授权


[root@amoeba ~]# vi /usr/local/amoeba/jvm.properties
在32行下面添加  斌且注释3232 #JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermS        ize=96m"
     33 JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"  #缓存空间大小设置


[root@amoeba ~]# vi /etc/init.d/amoeba
#!/bin/bash
#chkconfig: 35 20 90  
export JAVA_HOME=/usr/local/java  #运行环境
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
NAME=Amoeba  #变量名
AMOEBA_BIN=/usr/local/amoeba/bin/launcher  #二进制文件启动脚本
SHUTDOWN_BIN=/usr/local/amoeba/bin/shutdown  #二进制文件关闭脚本
PIDFILE=/usr/local/amoeba/Amoeba-MySQL.pid
SCRIPTNAME=/etc/init.d/amoeba   #脚本文件
case "$1" in
start)
echo -n "Staring $NAME..."  #提示
$AMOEBA_BIN  #启动
echo "done"  #输出信息
;;
stop)
echo -n "Stopping $NAME..."
$SHUTDOWN_BIN
rm -rf $PIDFILE   #删除进程文件
echo "done"
;;
restart)       #重启
$SHUTDOWN_BIN  #先执行关闭
sleep 1        #延时1秒
$AMOEBA_BIN    #后关闭
;;
*)
echo "Usage:$SCRIPTNAME {start|stop|restart}"
exit 1
esac

[root@amoeba ~]# chmod 755 /etc/init.d/amoeba  //添加授权
[root@amoeba ~]# chkconfig --add amoeba  //加入系统管理
[root@amoeba ~]# chkconfig --list   // 查询系统服务的默认启动状态

注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。 

      要列出 systemd 服务,请执行 'systemctl list-unit-files'。
      查看在具体 target 启用的服务请执行
      'systemctl list-dependencies [target]'。

amoeba         	0:1:2:3:4:5:6:关
netconsole     	0:1:2:3:4:5:6:关
network        	0:1:2:3:4:5:6:[root@amoeba ~]# systemctl start amoeba
[root@amoeba ~]# netstat -anpt | grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      44150/java          


在主从数据库上给amoeba授权

在主从数据库上

mysql> grant all privileges on *.* to 'test'@'192.168.188.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

在前端上授权客户端登录时用户名和密码

[root@amoeba ~]# vi /usr/local/amoeba/conf/amoeba.xml 
设置客户端连接amoeba前端服务器时使用的用户名和密码
检索password
                                        <property name="user">amoeba</property>

                                        <property name="password">123456</property>

设置读与写数据库的池
检索1500

  删除掉  <!--
                <property name="defaultPool">master</property>  #默认池
                
                <property name="writePool">master</property>   #主数据库负责写
                <property name="readPool">slaves</property>   #从数据库负责读

删除掉      -->

在这里插入图片描述
在这里插入图片描述


[root@amoeba ~]# vim /usr/local/amoeba/conf/dbServers.xml 
定义amoeba登录上数据库的授权用户名与密码



 26                         <property name="user">test</property>
 27 
 28                         <property name="password">123456</property>


设置主服务,地址
主数据库
 43         <dbServer name="master"  parent="abstractServer">
 46                         <property name="ipAddress">192.168.188.10</property>1
 50         <dbServer name="slave1"  parent="abstractServer">
 51                 <factoryConfig>
 52                         <!-- mysql ip -->
 53                         <property name="ipAddress">192.168.188.20</property>
 54                 </factoryConfig>
 55         </dbServer>2复制从1  657         <dbServer name="slave2"  parent="abstractServer">
 58                 <factoryConfig>
 59                         <!-- mysql ip --> 60                         <property name="ipAddress">192.168.188.30</property>
 61                 </factoryConfig>
 62         </dbServer>

在这里插入图片描述
在这里插入图片描述
设置定义池

检索Separated
 63         <dbServer name="slaves" virtual="true">

 69                         <property name="poolNames">slave1,slave2</property>

在这里插入图片描述
设置客户机


[root@client ~]# yum -y install mariadb*
[root@client ~]# systemctl start mariadb.service   //重启服务
[root@client ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> exit

[root@client ~]# mysql -uamoeba -p123456 -h 192.168.188.40 -P8066  //登录前端数据库,用户名amoeba,密码123456,ip地址192.168.188.40,端口号8066
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 65950793
Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> exit



MySQL [(none)]> use test;
Database changed
MySQL [test]> create table song(id int(10),name varchar(128),guanli varchar(128));
Query OK, 0 rows affected (0.03 sec)

MySQL [test]> insert into song values(1,'shufeng','this is master');
Query OK, 1 row affected (0.02 sec)

在主数据库上

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| song           |
+----------------+
1 row in set (0.00 sec)

mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
+------+---------+----------------+
1 row in set (0.00 sec)

从数据库1上

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
+------+---------+----------------+
1 row in set (0.00 sec)

从数据库2上


mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
+------+---------+----------------+
1 row in set (0.00 sec)

关闭主从同步复制,查看情况

主从复制关闭,再次添加数据,此时因为主数据库负责写操作,从数据库负责读操作,所以此时应只有主数据库上可以查看到新增的数据,从数据库上无变化
在客户端添加数据记录

客户机


MySQL [test]> insert into song values(2,'aaa','ccc');
Query OK, 1 row affected (0.00 sec)

从数据库

mysql> stop slave;  //关闭主从同步
Query OK, 0 rows affected (0.00 sec)

客户机

MySQL [test]> insert into song values(2,'bbb','ddd');
Query OK, 1 row affected (0.01 sec)

从数据库

mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
|    2 | aaa     | ccc            |
+------+---------+----------------+
2 rows in set (0.00 sec)

主数据库

mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
|    2 | aaa     | ccc            |
|    2 | bbb     | ddd            |
+------+---------+----------------+
3 rows in set (0.00 sec)

写入不同的数据,查看客户端读取时情况

从数据库1


mysql> delete from test.song;  //删除
Query OK, 2 rows affected (0.00 sec)
mysql> insert into test.song values(10011,'wangwu','qwe');
Query OK, 1 row affected (0.00 sec)
mysql> select * from song;
+-------+--------+--------+
| id    | name   | guanli |
+-------+--------+--------+
| 10011 | wangwu | qwe    |
+-------+--------+--------+
1 row in set (0.00 sec)


从数据库2

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> delete from test.song;
Query OK, 3 rows affected (0.00 sec)

mysql> select * from test.song;
Empty set (0.00 sec)

mysql> insert into test.song values(10012,'lisi','ddd');
Query OK, 1 row affected (0.00 sec)

mysql> select * from song;
+-------+------+--------+
| id    | name | guanli |
+-------+------+--------+
| 10012 | lisi | ddd    |
+-------+------+--------+
1 row in set (0.00 sec)

客户机
轮询的方式

MySQL [test]> select * from song;
+-------+--------+--------+
| id    | name   | guanli |
+-------+--------+--------+
| 10011 | wangwu | qwe    |
+-------+--------+--------+
1 row in set (0.02 sec)

MySQL [test]> 
MySQL [test]> 
MySQL [test]> select * from song;
+-------+------+--------+
| id    | name | guanli |
+-------+------+--------+
| 10012 | lisi | ddd    |
+-------+------+--------+
1 row in set (0.01 sec)

说明客户机提供Amoeba写入数据,写在主数据库上,从Amoeba中读取数据库信息,是从从数据库中读取的

主数据库


mysql> select * from song;
+------+---------+----------------+
| id   | name    | guanli         |
+------+---------+----------------+
|    1 | shufeng | this is master |
|    2 | aaa     | ccc            |
|    2 | bbb     | ddd            |
+------+---------+----------------+
3 rows in set (0.00 sec)

mysql> show master status;  //查看数据库的状态信息
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master_bin.000001 |     2660 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

恢复从数据库1与主数据库的主从同步
从数据库1


mysql> change master to master_host='192.168.188.10',master_user='myslave',master_password='123456',master_log_file='master_bin.000001',master_log_pos=2660;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;  //开启从状态
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G  //查看从数据库的状态信息
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.188.10
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master_bin.000001
          Read_Master_Log_Pos: 2660
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master_bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

从数据库2


mysql> show slave status\G  //查看从数据库的状态
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.188.10
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master_bin.000001
          Read_Master_Log_Pos: 2660
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 2117
        Relay_Master_Log_File: master_bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值