数据库相关

简单记录各中数据库常用crud命令。

Mysql

默认端口:3306

  • 查询是否锁表
mysql> show processlist;
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
| Id        | User     | Host               | db         | Command | Time  | State | Info             |
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
| 725067379 | mytestdb | 10.10.XX.15:35790  | test_event | Sleep   | 21286 |       | NULL             |
| 725362450 | mytestdb | 10.10.XX.15:39726  | test_event | Sleep   | 13862 |       | NULL             |
| 725816007 | mytestdb | 10.10.XX.222:49839 | test_event | Query   |     0 | NULL  | show processlist |
| 725822632 | mytestdb | 10.10.XX.15:58585  | test_event | Sleep   |     2 |       | NULL             |
| 725822668 | mytestdb | 10.10.XX.15:58660  | test_event | Sleep   |     0 |       | NULL             |
| 725822669 | mytestdb | 10.10.XX.15:58661  | test_event | Sleep   |     0 |       | NULL             |
| 725822671 | mytestdb | 10.10.XX.15:58666  | test_event | Sleep   |     0 |       | NULL             |
| 725822674 | mytestdb | 10.10.XX.15:58673  | test_event | Sleep   |     0 |       | NULL             |
| 725822675 | mytestdb | 10.10.XX.15:58677  | test_event | Sleep   |     0 |       | NULL             |
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
9 rows in set (0.00 sec)
  • 查询表中数据总数 -- Innod数据量过大这样查询速度很慢,需要给表加索引
mysql> select count(*) from dev_company_tax;
+----------+
| count(*) |
+----------+
| 12542793 |
+----------+
1 row in set (4.12 sec)
  • 查询某张表的索引
mysql> show index from test_company_tax;
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table           | Non_unique | Key_name          | Seq_in_index | Column_name     | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| dev_company_tax |          0 | PRIMARY           |            1 | id              | A         |    12787231 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | tax_number        |            1 | tax_number      | A         |    12787231 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | isshow            |            1 | isshow          | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | is_img_ok         |            1 | is_img_ok       | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | is_img_ok_2       |            1 | is_img_ok       | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | is_img_qichacha   |            1 | is_img_qichacha | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
| dev_company_tax |          1 | is_img_qichacha_2 |            1 | is_img_qichacha | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.34 sec)

extend:

通过MySQL命令查看
show index from tbname;

MySQL通过SQL语句查看表的索引:
1、查看数据库所有索引

SELECT * FROM mysql.`innodb_index_stats` a WHERE a.`database_name` = '数据库名';

2、查看某一表索引

SELECT * FROM mysql.`innodb_index_stats` a WHERE a.`database_name` = '数据库名' and a.table_name like '%表名%';

  • 导出指定数据库和其中的表信息
mysqldump -u root -p blog_service > blog_service.sql
  • 导入 xxx.sql 到数据库中
mysql -u blog_service < blog_service.sql

当然,也可以用Navicat等图形化工具导入xxx.sql文件。但要注意Navicat导入数据库前要先创建一个同名空数据库,然后再运行sql文件。

Redis

默认端口:6379

能系统安装就不要自己手动装了。

1. Ubuntu安装redis

apt安装

sudo apt-get install redis-server

手动安装 (不推荐)

(详见此文)[https://jingyan.baidu.com/article/00a07f38173cea82d028dc24.html]

下载:wget http://download.redis.io/releases/redis-3.0.6.tar.gz

解压:tar -zxvf redis-3.0.6.tar.gz

编译:cd redis-3.0.6 && make MALLOC=libc

安装:sudo make install

2. Redis常用命令 (on Ubuntu)

一般来说,会在redis安装目录下面,配置一个redis.conf的文件来定制化启动redis

检查Redis是否挂了
ps -ef | grep redis

test@xxx:/data/$ ps -ef | grep redis
ubuntu    6673     1  0  8月19 ?      01:59:52 redis-server *:6379
1.Redis server 6379挂了时,启动reids (带启动文件)

进入redis安装目录

执行下面命令的其中1条:
sudo redis-server redis.conf
sudo ./redis-server  ./redis.conf

2.Redis server 没挂时,重启redis

sudo service redis-server restart
sudo /etc/init.d/redis-server restart

or

sudo systemctl restart redis-server   (apt或yum安装的redis)



[sudo] password for ubuntu:
Stopping redis-server: redis-server.
Starting redis-server: redis-server.

如果是用apt-get或者yum install安装的redis,可以直接通过下面的命令停止/启动/重启redis.

/etc/init.d/redis-server stop
/etc/init.d/redis-server start
/etc/init.d/redis-server restart

3.Redis问题解决

REDIS 启动警告及处理 -- 推荐

redis超时原因系统性排查

1. overcommit_memory
2. THP (Transparent Huge Pages)
3. TCP backlog

1. overcommit_memory

错误日志:

ResponseError: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.

参考解决方案

解决实施参考

很多人都是建议“config set stop-writes-on-bgsave-error no”。这样做其实是不好的,这仅仅是让程序忽略了这个异常,使得程序能够继续往下运行,但实际上数据还是会存储到硬盘失败。

当操作系统收到内存分配请求时,它会依据overcommit_memory 设定的条件,考虑接受或者拒绝这个请求

0 — 默认设置 内核使用启发式算法,来估算可用的内存量,直接拒绝不合理的请求
1 — 内核不考虑内存是否够用,直接同意请求,在这种设置下,潜在的内存过载风险增加了,但有利于内存密集型任务
2 — 如果程序请求的内存分配大于等于 交换分区和物理内存的总和 * overcommit_ratio / 100 则拒绝这个请求 默认是 交换分区和物理内存总和的50%

默认设置是0,只要内存请求超过物理内存的剩余量,请求就会被拒绝。 设置1,不管实际物理内存使用量,直接同意请求。设置1是一种比较粗放式的对内存请求的管理方式,我认为更为优雅的方式是使用2,并且将overcommit_ratio 的值设为60 ~ 80

解决方法:

细致式:

echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
echo "vm.overcommit_ratio=70" >> /etc/sysctl.conf
sysctl -p

sysctl -p 不用重启使配置生效

粗旷式:

echo "vm.overcommit_memory=1" >> /etc/sysctl.conf

2. THP(Transparent Huge Pages)透明大页

透明大页,默认是always,启用是为了可以管理更多的内存地址空间。可以使用never关闭,之后会使用系统软件的算法管理内存映射。

通常linux会将透明大页开启,在fork被调用后,redis产生的延迟被用来持久化到磁盘。内存大页会引起一下问题:
 1.fork被调用,共享内存大页的两个进程被创建
 2.在一个系统比较活跃的实例里,部分循环时间运行需要几千个内存页,期间引起的copy-on-write 会消耗几乎所有的内存
 3.这个将导致更大的延迟和使用更多的内存

因此,redis官方建议需要确保禁掉内存大页:
echo never > /sys/kernel/mm/transparent_hugepage/enabled

错误日志:

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

使用的是透明大页,可能导致redis延迟和内存使用问题。

查看是否使用透明大页

➜  cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]

Linux默认设置使[always]

解决使用的是透明大页,可能导致redis延迟和内存使用问题。

解决方法:

临时解决方法

sudo su    #  先切换到root用户
echo never > /sys/kernel/mm/transparent_hugepage/enabled     # root用户执行此命令

➜ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]     # 选择的使never说明设置成功,默认是[always]



永久解决方法:

将其写入/etc/rc.local文件中:

iftest -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then

echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

fi

3. TCP backlog

常见报错:

# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

# Server started, Redis version 3.2.6

对于linux 而言backlog 是指已经完成了3次握手,且等待 accept 的连接 如果被没有被accept, 连接会一直在队列中排队,队列的最大长度为 backlog 由此可知, 在client非常多且创建和关闭连接非常频繁的场景下,这个参数会非常有用。

解决方法:

echo "net.core.somaxconn = 511" >> /etc/sysctl.conf
sysctl -p

Redis主从复制

redis的主从复制

MongoDB

默认端口:27017

常用命令:

1.检查mongod启动没有
pgrep mongo -l

2.mongodb的后台启动,配置文件(mongodb.conf)自己写(能不用root就别用root),日志注意不要写到/var下
mongod --config /etc/mongodb.conf   

PostgreSQL

默认端口:5432

其他问题

关系型数据库数据搜索缺点

1.无法打分(无法对搜索出来的结果进行排序)

2.无分布式

3.无法解析搜索请求

4.效率低(上亿)

5.分词

如何对数据库进行优化