暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

openGauss6.0 LTS 系统技术解析:日常操作深度探索

原创 shunwah 2024-12-05
925

作者:ShunWah

在运维管理领域,我拥有多年深厚的专业积累,兼具坚实的理论基础与广泛的实践经验。我始终站在技术前沿,致力于推动运维自动化,不懈追求运维效率的最大化。

我精通运维自动化流程,对于OceanBase、MySQL等多种数据库的部署与运维,具备从初始部署到后期维护的全链条管理能力。凭借OceanBase的OBCA和OBCP认证、OpenGauss社区认证结业证书,以及崖山DBCA、亚信AntDBCA、翰高HDCA、GBase 8a | 8c | 8s、Galaxybase GBCA、Neo4j Graph Data Science Certification、NebulaGraph NGCI & NGCP等多项权威认证,我不仅展现了自己的专业技能,也彰显了对技术的深厚热情与执着追求。

在OceanBase & 墨天轮的技术征文大赛中,我凭借卓越的技术实力和独特的见解,多次荣获一、二、三等奖。同时,在OpenGauss第五届、第六届、第七届技术征文大赛,TiDB社区第三届专栏征文大赛,金仓数据库有奖征文活动,以及首批YashanDB「产品体验官」尝鲜征文等活动中,我也屡获殊荣。此外,我还活跃于墨天轮、CSDN等技术平台,经常发布原创技术文章,并多次被首页推荐,积极与业界同仁分享我的运维经验和独到见解。

image.png

前言

自openGauss社区联合Gauss松鼠会、墨天轮社区共同举办第八届openGauss技术文章征集活动以来,我作为openGauss的忠实用户,一直积极参与其中,分享我的使用心得和技术实践。今天,我想借此机会,与大家分享我与openGauss的故事,以及我在使用过程中的一些技术见解和实践经验。

openGauss,作为一款由华为开源的关系型数据库管理系统,自诞生之日起就承载着自主可控与技术创新的重大使命。它基于PostgreSQL研发,专为OLTP场景优化,提供了面向多核架构的极致性能、全链路的业务数据安全、基于AI的调优和高效运维的能力。这些特性使得openGauss在众多开源数据库中脱颖而出,成为了我技术探索的首选目标。

在数据驱动的时代,数据库作为数据存储和管理的核心,其性能和稳定性至关重要。openGauss,作为一款开源的关系型数据库管理系统,凭借其高性能、高可扩展性和高安全性,逐渐在业界崭露头角。本文将深入解析openGauss的系统技术,特别是通过命令行操作,展现其强大的功能和灵活性。

一、openGauss系统架构概览

openGauss采用分布式架构,支持多节点部署,提供了高可用性和数据容灾能力。其核心组件包括数据库引擎、存储引擎、通信模块和安全模块等。通过命令行,我们可以直观地管理和配置这些组件,实现数据库的优化和运维。
数据库
数据库用于管理各类数据对象,与其他数据库隔离。创建数据对象时可以指定对应的表空间,如果不指定相应的表空间,相关的对象会默认保存在PG_DEFAULT空间中。数据库管理的对象可分布在多个表空间上。

1、表空间

在openGauss中,表空间是一个目录,可以存在多个,里面存储的是它所包含的数据库的各种物理文件。由于表空间是一个目录,仅是起到了物理隔离的作用,其管理功能依赖于文件系统。

2、模式

openGauss的模式是对数据库做一个逻辑分割。所有的数据库对象都建立在模式下面。openGauss的模式和用户是弱绑定的,所谓的弱绑定是指虽然创建用户的同时会自动创建一个同名模式,但用户也可以单独创建模式,并且为用户指定其他的模式。

3、用户和角色

openGauss使用用户和角色来控制对数据库的访问。根据角色自身的设置不同,一个角色可以看做是一个数据库用户,或者一组数据库用户。在openGauss中角色和用户之间的区别只在于角色默认是没有LOGIN权限的。在openGauss中一个用户唯一对应一个角色,不过可以使用角色叠加来更灵活地进行管理。

4、事务管理

在事务管理上,openGauss采取了MVCC(多版本并发控制)结合两阶段锁的方式,其特点是读写之间不阻塞。openGauss没有将历史版本数据统一存放,而是和当前元组的版本放在了一起。openGauss没有回滚段的概念,但是为了定期清除历史版本数据引入了一个VACUUM线程。一般情况下用户不用关注它,除非要做性能调优。此外,openGauss是自动提交事务。

二、命令行操作基础

1、连接数据库

数据库安装完成后,默认生成名称为postgres的数据库。第一次连接数据库时可以连接到此数据库。

执行如下命令连接数据库。

[gauss@worker3 ~]$ gsql -d postgres -p 5432 -C
gsql ((openGauss 6.0.0 build aee4abd5) compiled at 2024-09-29 18:38:08 commit 0 last mr  )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

openGauss=# 

image.png

其中postgres为需要连接的数据库名称,5432为数据库主节点的端口号。请根据实际情况替换。
连接成功后,系统提示“Non-SSL connection”表示未使用SSL方式连接数据库。如果需要高安全性时,请使用SSL连接。

2、用户管理

2.1 执行下面的命令,查看有哪些用户:
openGauss=# \du
                                                              List of roles
 Role name |                                                    Attributes                                                    | Member of 
-----------+------------------------------------------------------------------------------------------------------------------+-----------
 dim       | Create DB                                                                                                        | {}
 gauss     | Sysadmin, Create role, Create DB, Replication, Administer audit, Monitoradmin, Operatoradmin, Policyadmin, UseFT | {}
 jim       | Create role                                                                                                      | {}
 my_root   | Sysadmin                                                                                                         | {}

openGauss=# 

image.png

2.2 创建用户openuser

执行下面的SQL语句,创建用户openuser:

openGauss=#     
openGauss=# CREATE USER openuser WITH PASSWORD 'Opgshua@1234';
NOTICE:  The encrypted password contains MD5 ciphertext, which is not secure.
CREATE ROLE
openGauss=# 

image.png

2.3 授予openuser数据库系统的SYSADMIN权限:
openGauss=# ALTER USER openuser SYSADMIN;
ALTER ROLE
openGauss=# \du 
                                                              List of roles
 Role name |                                                    Attributes                                                    | Member of 
-----------+------------------------------------------------------------------------------------------------------------------+-----------
 dim       | Create DB                                                                                                        | {}
 gauss     | Sysadmin, Create role, Create DB, Replication, Administer audit, Monitoradmin, Operatoradmin, Policyadmin, UseFT | {}
 jim       | Create role                                                                                                      | {}
 my_root   | Sysadmin                                                                                                         | {}
 openuser  | Sysadmin                                                                                                         | {}

openGauss=# 

image.png

3、 数据库管理

3.1 创建数据库
a. 使用如下命令创建一个新的表空间tpcds_local。
openGauss=# 
openGauss=# CREATE TABLESPACE tpcds_local RELATIVE LOCATION 'tablespace/tablespace_1' ;
CREATE TABLESPACE
openGauss=# 

image.png

b. 使用如下命令创建一个新的数据库db_tpcc。
openGauss=# CREATE DATABASE db_tpcc WITH TABLESPACE = tpcds_local;
CREATE DATABASE
openGauss=# 

image.png

说明:
数据库名称遵循SQL标识符的一般规则。当前角色自动成为此新数据库的所有者。

如果一个数据库系统用于承载相互独立的用户和项目,建议把它们放在不同的数据库里。

如果项目或者用户是相互关联的,并且可以相互使用对方的资源,则应该把它们放在同一个数据库里,但可以规划在不同的模式中。模式只是一个纯粹的逻辑结构,某个模式的访问权限由权限系统模块控制。

创建数据库时,若数据库名称长度超过63字节,server端会对数据库名称进行截断,保留前63个字节,因此建议数据库名称长度不要超过63个字节。

4、查看数据库

使用\l元命令查看数据库系统的数据库列表。

openGauss=# \l
                              List of databases
   Name    | Owner | Encoding |   Collate   |    Ctype    | Access privileges 
-----------+-------+----------+-------------+-------------+-------------------
 db_tpcc   | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 finance   | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/gauss        +
           |       |          |             |             | gauss=CTc/gauss  +
           |       |          |             |             | jim=c/gauss
 school    | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/gauss         +
           |       |          |             |             | gauss=CTc/gauss
 template1 | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/gauss         +
           |       |          |             |             | gauss=CTc/gauss
 testdb    | gauss | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
(7 rows)

openGauss=# 

image.png

或使用如下命令通过系统表pg_database查询数据库列表。

openGauss=# SELECT datname FROM pg_database;
  datname  
-----------
 template1
 school
 finance
 template0
 testdb
 postgres
 db_tpcc
(7 rows)

openGauss=# 

image.png

5、修改数据库

用户可以使用如下命令修改数据库属性(比如:owner、名称和默认的配置属性)。

5.1 使用以下命令为数据库设置默认的模式搜索路径。
openGauss=# ALTER DATABASE db_tpcc SET search_path TO pa_catalog,public;
ALTER DATABASE
openGauss=# 

image.png

5.2 使用如下命令修改数据库表空间。
openGauss=# ALTER DATABASE db_tpcc SET TABLESPACE tpcds_local;
ALTER DATABASE
openGauss=# 

image.png

5.3 使用如下命令为数据库重新命名。
openGauss=# ALTER DATABASE db_tpcc RENAME TO human_tpcds;
ALTER DATABASE
openGauss=# 

image.png

6、删除数据库

用户可以使用DROP DATABASE命令删除数据库。这个命令删除了数据库中的系统目录,并且删除了磁盘上带有数据的数据库目录。用户必须是数据库的owner或者系统管理员才能删除数据库。当有人连接数据库时,删除操作会失败。删除数据库时请先连接到其他的数据库。

使用如下命令删除数据库:

openGauss=# DROP DATABASE human_tpcds;
DROP DATABASE
openGauss=# 

image.png

7、断开数据库

要断开连接,只需在psql环境中输入\q并回车。

openGauss=# \q
[gauss@worker3 single_node]$ 

image.png

三、高级命令行操作

以操作系统用户gauss登录数据库主节点。

1、使用gs_dump导出postgres数据库。

[gauss@worker3 backup]$ ls
[gauss@worker3 backup]$ gs_dump -U gauss -f /home/gauss/backup/userdatabase_backup.tar -p 5432 postgres -F t 
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: Begin scanning database. 
Progress: [==================================================] 100% (38/37, cur_step/total_step). finish scanning database                       
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: Finish scanning database. 
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: Start dumping objects 
Progress: [==================================================] 100% (4839/4839, dumpObjNums/totalObjNums). dump objects 
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: Finish dumping objects 
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: dump database postgres successfully
gs_dump[port='5432'][postgres][2024-12-05 10:03:16]: total time: 167  ms
[gauss@worker3 backup]$ ls
userdatabase_backup.tar
[gauss@worker3 backup]$ 

image.png

参数说明
-U 连接数据库的用户名。
例 -U gauss

-f 将导出文件发送至指定目录文件夹。如果这里省略,则使用标准输出。如果输出格式为(-F c/-F d/-F t)时,必须指定-f参数。
例 -f /home/omm/backup/postgres_backup.tar

-p 指定服务器所侦听的TCP端口或本地Unix域套接字后缀,以确保连接。
例 -p 5432

dbname 需要导出的数据库名称。
例:postgres

-F 选择导出文件格式。-F参数值如下:
p:纯文本格式
c:自定义归档
d:目录归档格式
t:tar归档格式
例:-F t

2、使用gs_restore命令导入数据

gs_restore默认是以追加的方式进行数据导入。为避免多次导入造成数据异常,在进行导入时,建议选择使用“-c”和“-e”参数。“-c”表示在重新创建数据库对象前,清理(删除)已存在于将要还原的数据库中的数据库对象;“-e”表示当发送SQL语句到数据库时如果出现错误请退出,默认状态下会继续,且在导入后会显示一系列错误信息。
使用gs_restore命令,从postgres整个数据库内容的导出文件中,将数据库的所有对象的定义导入到backupdb。

[gauss@worker3 ~]$ cd backup/
[gauss@worker3 backup]$ ls
userdatabase_backup.tar
[gauss@worker3 backup]$ gs_restore -U gauss /home/gauss/backup/userdatabase_backup.tar -p 5432 -d bkupdb_tpcc -s -e -c
start restore operation ...
Progress: [==================================================] 100% (14/14, restored_entries/total_entries). restore entires 
end restore operation ...
restore operation successful
total time: 62  ms
[gauss@worker3 backup]$ 

image.png

四、 性能监控

1、查看活动会话

SELECT * FROM pg_stat_activity;
openGauss=# SELECT * FROM pg_stat_activity;
 datid | datname  |       pid       |    sessionid    | usesysid | usename |    application_name    | client_addr | client_hostname | client_port
 |         backend_start         |          xact_start           |          query_start          |         state_change          | waiting | enqu
eue | state  | resource_pool |     query_id     |                 query                  |                                                       
 connection_info                                                         | unique_sql_id | trace_id 
-------+----------+-----------------+-----------------+----------+---------+------------------------+-------------+-----------------+------------
-+-------------------------------+-------------------------------+-------------------------------+-------------------------------+---------+-----
----+--------+---------------+------------------+----------------------------------------+-------------------------------------------------------
-------------------------------------------------------------------------+---------------+----------
 15743 | postgres | 139970039772928 | 139970039772928 |       10 | gauss   | JobScheduler           |             |                 |            
 | 2024-12-04 21:25:05.355947+08 |                               |                               | 2024-12-05 10:18:53.793941+08 | f       |     
    | active | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969934391040 | 139969934391040 |       10 | gauss   | ApplyLauncher          |             |                 |            
 | 2024-12-04 21:25:05.298277+08 |                               |                               | 2024-12-04 21:25:05.352389+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969846834944 | 139969846834944 |       10 | gauss   | TxnSnapCapturer        |             |                 |            
 | 2024-12-04 21:25:05.300973+08 |                               |                               | 2024-12-04 21:25:05.355226+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969822652160 | 139969822652160 |       10 | gauss   | CfsShrinker            |             |                 |            
 | 2024-12-04 21:25:05.311665+08 |                               |                               | 2024-12-04 21:25:05.351865+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969595700992 | 139969595700992 |       10 | gauss   | workload               |             |                 |            
 | 2024-12-04 21:25:05.343428+08 | 2024-12-04 21:25:05.348886+08 | 2024-12-04 21:25:05.348886+08 | 2024-12-04 21:25:05.354162+08 | f       |     
    | active | default_pool  |                0 | WLM fetch collect info from data nodes |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969743484672 | 139969743484672 |       10 | gauss   | Asp                    |             |                 |            
 | 2024-12-04 21:25:05.354582+08 |                               |                               | 2024-12-05 10:18:53.3677+08   | f       |     
    | active | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969702655744 | 139969702655744 |       10 | gauss   | statement flush thread |             |                 |            
 | 2024-12-04 21:25:05.354325+08 |                               |                               | 2024-12-04 21:25:05.354343+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969780250368 | 139969780250368 |       10 | gauss   | PercentileJob          |             |                 |            
 | 2024-12-04 21:25:05.362856+08 |                               |                               | 2024-12-05 10:18:52.732024+08 | f       |     
    | active | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969568962304 | 139969568962304 |       10 | gauss   | WorkloadMonitor        |             |                 |            
 | 2024-12-04 21:25:05.353093+08 |                               |                               | 2024-12-04 21:25:05.360247+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
                                                                         |             0 | 
 15743 | postgres | 139969510766336 | 139969510766336 |       10 | gauss   | WLMArbiter             |             |                 |            
 | 2024-12-04 21:25:05.359067+08 |                               |                               | 2024-12-04 21:25:05.362233+08 | f       |     
    | idle   | default_pool  |                0 |                                        |                                                       
Cancel request sent
openGauss=# 

image.png

2、查看openGauss内节点CPU使用情况

通过top命令查看openGauss内节点CPU使用情况,分析是否存在由于CPU负载过高导致的性能瓶颈。 top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况。

[gauss@worker3 backup]$ top -H
top - 10:24:02 up 17 days,  1:12,  2 users,  load average: 0.02, 0.04, 0.05
Threads: 591 total,   1 running, 590 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 28802768 total, 22951876 free,  1606764 used,  4244128 buff/cache
KiB Swap:  8388604 total,  8388604 free,        0 used. 26217800 avail Mem 

image.png

3、性能参数分析

如果是“USER”为gauss的openGauss进程CPU占用过高,请根据目前运行的业务查询内容,对业务SQL进行优化。请根据以下步骤,并结合当前正在运行的业务特征进行分析,是否该程序处于死循环逻辑。

a. 使用“top -H -p pid”查找进程内占用的CPU百分比较高的线程,进行分析。
[gauss@worker3 backup]$ top -H -p 5960
top - 10:25:21 up 17 days,  1:14,  2 users,  load average: 0.00, 0.03, 0.05
Threads:  40 total,   0 running,  40 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.1 sy,  0.0 ni, 99.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 28802768 total, 22957352 free,  1601268 used,  4244148 buff/cache
KiB Swap:  8388604 total,  8388604 free,        0 used. 26223296 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                     
  5945 gauss     20   0 6476808 1.102g 253844 S  0.7  4.0   1:57.75 pagewriter                                                                  
  5960 gauss     20   0 6476808 1.102g 253844 S  0.7  4.0   3:38.23 ashworker                                                                   
  5959 gauss     20   0 6476808 1.102g 253844 S  0.3  4.0   1:37.58 percentworker                                                               
  5967 gauss     20   0 6476808 1.102g 253844 S  0.3  4.0   3:29.19 undorecycler                                                                
  5899 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:01.55 gaussdb                                                                     
  5900 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 jemalloc_bg_thd                                                             
  5906 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 gaussdb                                                                     
  5907 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.23 syslogger                                                                   
  5908 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.67 auditor                                                                     
  5909 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:05.78 alarm                                                                       
  5910 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 jemalloc_bg_thd                                                             
  5911 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 jemalloc_bg_thd                                                             
  5912 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.13 reaper                                                                      
  5913 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 jemalloc_bg_thd                                                             
  5937 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 gaussdb                                                                     
  5938 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 gaussdb                                                                     
  5939 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 gaussdb                                                                     
  5941 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:09.49 checkpointer                                                                
  5942 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 Spbgwriter                                                                  
  5943 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.72 pagewriter                                                                  
  5944 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.72 pagewriter                                                                  
  5946 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.75 pagewriter                                                                  
  5947 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.70 pagewriter                                                                  
  5948 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:05.93 WALwriter                                                                   
  5949 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 WALwriteraux                                                                
  5950 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.43 AVClauncher                                                                 
  5952 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:05.94 Jobscheduler                                                                
  5953 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:00.00 asyncundolaunch                                                             
  5954 gauss     20   0 6476808 1.102g 253844 S  0.0  4.0   0:01.67 globalstats                                                                 
[gauss@worker3 backup]$ 

image.png

查询结果如下所示,top中可以看到占用CPU很高的线程,下面以线程5945为主,分析其为何占用CPU过高。

b. 使用“gstack ”查看进程内各线程的函数调用栈。查找上一步骤中占用CPU较高的线程ID对应的线程号。
[gauss@worker3 backup]$ gstack 5945
Thread 1 (process 5945):
#0  0x00007f4e5fdebddd in poll () from /lib64/libc.so.6
#1  0x00005608493333c8 in WaitLatchOrSocket(Latch volatile*, int, int, long) ()
#2  0x0000560849b9d17e in ckpt_pagewriter_main() ()
#3  0x0000560849b4834a in int GaussDbThreadMain<(knl_thread_role)46>(knl_thread_arg*) ()
#4  0x0000560849b1cdc5 in ?? ()
#5  0x00007f4e600cdea5 in start_thread () from /lib64/libpthread.so.0
#6  0x00007f4e5fdf6b0d in clone () from /lib64/libc.so.6
[gauss@worker3 backup]$ 

image.png

四、总结

openGauss作为一款高性能、高可扩展性的开源数据库,其命令行操作提供了丰富的功能,使得数据库管理变得更加灵活和高效。通过掌握这些命令行操作技巧,我们可以更好地管理和优化openGauss数据库,满足各种复杂的应用场景需求。希望本文能够为您的openGauss之旅提供有益的参考和帮助。

最后修改时间:2024-12-11 16:28:25
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论