Rootop 服务器运维与web架构

2020-09-16
发表者 Venus
mysql redo log 重做日志已关闭评论

mysql redo log 重做日志

资料:https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log.html
重做日志用于数据库崩溃后未写入到数据库中数据的恢复。
重做日志默认文件名叫 ib_logfile0 和 ib_logfile1两个个文件。
# 这俩文件的当前大小通过下面变量查看(单位字节)

SHOW VARIABLES LIKE 'innodb_log_file_size'; 

# 当前的重做日志个数通过下面变量查看

SHOW VARIABLES LIKE 'innodb_log_files_in_group';

如果想改变重做日志的数量和大小,按照以下步骤操作:
1、停止数据库并确定没有报错
2、修改my.cnf,添加

# 数量最大值100,比如这里设置为5个
innodb_log_files_in_group = 5
# 单个文件大小不能超过512GB/innodb_log_files_in_group
innodb_log_file_size = 1024000000
# 设置文件路径,默认在 SHOW VARIABLES LIKE 'datadir'; 目录下
innodb_log_group_home_dir = /usr/local/mysql/data


3、启动mysql

比如 https://www.rootop.org/pages/4797.html 这个错误就是重做日志大小发生改变,导致启动时检测到文件大小错误。

2020-09-10
发表者 Venus
mysql中创建纯数字的数据库及删除已关闭评论

mysql中创建纯数字的数据库及删除

在mysql中创建纯数字数据库是不合标准的,默认会提示语法错误,但通过mysql转义符 ` 还是可以创建。

CREATE DATABASE 222;

报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '222' at line 1

# 加上转义符

CREATE DATABASE `222`;

成功。

# 查询语句

SELECT * FROM 222.aaa WHERE id = 1;

报错:
错误码: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '222.aaa WHERE id = 1' at line 1

# 加上转义符查询

SELECT * FROM `222`.aaa WHERE id = 1;

可以查询

# 删除加转义符删除

DROP DATABASE `222`;

2020-09-10
发表者 Venus
mysql用户权限已关闭评论

mysql用户权限

mysql.user表用户权限相关字段的含义:

Select_priv   		  #查询
Insert_priv  		  #插入
Update_priv  		  #修改
Delete_priv   		  #删除
Create_priv   		  #创建数据库或表
Drop_priv     		  #删除数据库或表
Reload_priv   		  #执行刷新和重新加载MySQL所用各种内部缓存的特定命令,包括日志、权限、主机、查询和表重新加载权限表  
Shutdown_priv 		  #关闭MySQL服务,在将此权限提供给root账户之外的任何用户时,都应当非常谨慎 
Process_priv  		  #用户是否可以通过SHOW PROCESSLIST命令查看其他用户的进程服务器管理  
File_priv     		  #用户是否可以执行SELECT INTO OUTFILE和LOAD DATA INFILE命令加载服务器上的文件  
Grant_priv    		  #用户是否可以将已经授予给该用户自己的权限再授予其他用户(任何用户赋予全部已有权限
References_priv 	  #目前只是某些未来功能的占位符;现在没有作用  
Index_priv      	  #用户是否可以创建和删除表索及引用索引查询表
Alter_priv      	  #用户是否可以重命名和修改表结构
Show_db_priv    	  #用户是否可以查看服务器上所有数据库的名字,包括用户拥有足够访问权限的数据库可以考虑对所有用户禁用这个权限,除非有特别不可抗拒的原因
Super_priv      	  #用户是否可以执行某些强大的管理功能,例如通过KILL命令删除用户进程,使用SET GLOBAL修改全局MySQL变量,执行关于复制和日志的各种命令超级权限  
Create_tmp_table_priv #用户是否可以创建临时表
Lock_tables_priv      #用户是否可以使用LOCK TABLES命令阻止对表的访问/修改
Execute_priv          #用户是否可以执行存储过程此权限只在MySQL 5.0及更高版本中有意义
Repl_slave_priv		  #用户是否可以读取用于维护复制数据库环境的二进制日志文件此用户位于主系统中,有利于主机和客户机之间的通信主服务器管理 
Repl_client_priv 	  #用户是否可以确定复制从服务器和主服务器的位置从服务器管理
Create_view_priv 	  #用户是否可以创建视图此权限只在MySQL 5.0及更高版本中有意义
Show_view_priv 		  #用户是否可以查看视图或了解视图如何执行此权限只在MySQL 5.0及更高版本中有意义  
Create_routine_priv   #用户是否可以更改或放弃存储过程和函数此权限是在MySQL 5.0中引入的  
Alter_routine_priv    #用户是否可以修改或删除存储函数及函数此权限是在MySQL 5.0中引入的  
Create_user_priv      #用户是否可以执行CREATE USER命令,这个命令用于创建新的MySQL账户  
Event_priv 			  #用户是否创建、修改和删除事件这个权限是MySQL 5.1.6新增的
Trigger_priv 		  #用户是否创建和删除触发器,这个权限是MySQL 5.1.6新增的  
Create_tablespace_priv#用户是否可以创建表空间 

# GRANT赋权的关键词和数据库中mysql.user表权限字段对应关系参考链接
https://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html

# 指定全部权限,mysql.user 表中会体现出权限控制信息
GRANT ALL PRIVILEGES ON *.* TO 'user1'@'1.1.1.1' IDENTIFIED BY '111111';

# 指定库的权限,会在 mysql.db 表中体现出精细到指定库的信息
GRANT SELECT,INSERT,UPDATE ON ops.* TO 'user1'@'%';

# 指定库指定表的权限,会在 mysql.tables_priv 表中体现出权限精细到某张表的信息
GRANT SELECT,INSERT,UPDATE ON ops.ding TO 'user1'@'%';

# 指定某表的某列权限,会在 mysql.columns.priv 表中体现出来
GRANT SELECT(`age`),UPDATE(`age`) ON aaa.info TO 'user1'@'%';
#测试
#mysql> update info set age = 1 where id =1;
#ERROR 1143 (42000): SELECT command denied to user 'user1'@'x.x.x.x' for column 'id' in table 'info'
#mysql> update info set age = 1 where age = 11;
#Query OK, 1 row affected (0.03 sec)

# 刷新内存中的权限
FLUSH PRIVILEGES;

# 查看用户权限
SHOW GRANTS FOR 'user1';


# 赋权语句解析
GRANT ALL PRIVILEGES ON *.* TO 'user1'@'%' IDENTIFIED BY '111111' WITH GRANT OPTION;

ALL PRIVILEGES:表示将所有权限赋给用户。也可指定具体的权限,如:SELECT、UPDATE、INSERT等。
ON:这些权限对哪些数据库和表生效,第一个*号是数据库名,第二个*号是表名
TO:将权限赋予哪个用户。用户名@地址,所有地址用%表示,或者可以指定具体ip、ip段、主机名。
IDENTIFIED BY:指定用户的密码。
WITH GRANT OPTION:允许用户将自己的权限赋权给其它用户。

2020-09-09
发表者 Venus
nginx通过geoip2模块实现区分城市省份的跳转已关闭评论

nginx通过geoip2模块实现区分城市省份的跳转

mmdblookup命令由 https://github.com/maxmind/libmaxminddb/releases 提供。
ip数据库文件从 https://dev.maxmind.com/geoip/geoip2/geolite2/ 下载 geolite2版(免费版),需要登录才能下。
过程略。

# 获取所有ip信息
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip 1.1.1.1
会返回一个类似json格式的数据,但并不是json。这里截取部分返回信息:
 "country": 
      {
        "geoname_id": 
          2077456 <uint32>
        "iso_code": 
          "AU" <utf8_string>
        "names": 
          {
            "de": 
              "Australien" <utf8_string>
            "en": 
              "Australia" <utf8_string>
            "es": 
              "Australia" <utf8_string>
            "fr": 
              "Australie" <utf8_string>
            "ja": 
              "オーストラリア" <utf8_string>
            "pt-BR": 
              "Austrália" <utf8_string>
            "ru": 
              "Австралия" <utf8_string>
            "zh-CN": 
              "澳大利亚" <utf8_string>
          }
      }

比如要返回iso_code值,则传递 country 和 iso_code 2个值给命令

[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip 1.1.1.1 country iso_code

  "AU" <utf8_string>

 

# 获取国家
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x country iso_code
# 获取城市
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x city names en
# 获取省份
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x subdivisions 0 names en

这些字段在nginx配置文件中同样适用。了解完返回的ip信息结构后,现在实现一个需求。
当客户端来源ip在被屏蔽的城市或者省份时,且访问的地址不是/new.html,则跳转到/new.html页面。其它的则不跳转。

# nginx配置,在http段,geoip2和map指令只能存在于http段中。
# 通过map指令实现定义要屏蔽的城市和省份名单

geoip2 /home/mmdb/GeoLite2-City.mmdb
{
	#default是为了当ip查不到信息时设置一个默认值。
	$country default=CN country iso_code;
    $city_name default=Beijing city names en;
	$province default=Shandong subdivisions 0 names en;
}

# 定义城市名单
map $city_name $allow_city
{
	default yes;
	Beijing no;
	Guangzhou no;
	Shanghai no;
	Shenzhen no;
}

# 定义省份名单
map $province $allow_province
{
	default yes;
	Shandong no;
}
	
# 在虚拟主机段
server
{
	# 拒绝国外访问
	if ( $country != "CN" )
	{
		return 403;
	}

	set $jump "0";
	# 判断是否访问的为new.html,防止出现死循环跳转。
	if ($uri != '/new.html')
	{
	  set $jump "${jump}0";
	}
	
	if ( $allow_city = "no" )
	{
	  set $jump "${jump}1";
	}
	
	if ( $allow_province = "no" )
	{
	  set $jump "${jump}1";
	}
	
	if ( $jump = "001" )
	{
		return 301 http://x.x.x.x/new.html;
	}
	
	if ( $jump = "0011" )
	{
		return 301 http://x.x.x.x/new.html;
	}
	
	# 通过浏览器响应头查看ip所属地信息
	add_header city $city_name;
	add_header province $province;
	add_header jump $jump;
}

测试,略。

注意:GeoLite2-City.mmdb这个开源的地址库,ip并不是很准确,包括会出现查不到的ip。
推测这些变量可以写到访问日志中记录,未测试。

2020-09-04
发表者 Venus
chrome浏览器中网络错误的3种情况 ERR_CONNECTION_TIMED_OUT、ERR_CONNECTION_REFUSED、ERR_CONNECTION_RESET已关闭评论

chrome浏览器中网络错误的3种情况 ERR_CONNECTION_TIMED_OUT、ERR_CONNECTION_REFUSED、ERR_CONNECTION_RESET

# 服务端监听端口,但拒绝接收syn包,或者网络不通。
比如iptables中拒绝掉syn标记的包

iptables -A INPUT -p tcp --dport 80 --syn -j DROP

以下错误是chrome浏览器访问时的报错信息:
ERR_CONNECTION_TIMED_OUT #客户端发送了syn包,但未收到回应的syn+ack包(服务端不响应),而且客户端一直在重传syn。

# 服务端未监听端口
ERR_CONNECTION_REFUSED #客户端发送了syn,服务端响应了rst+ack,客户端重传,服务端依旧响应rst+ack,3次握手无法建立。

# IP被墙
ERR_CONNECTION_RESET #客户端发送syn,服务器响应syn+ack,客户端回应ack,3次握手完成,客户端发起http请求,服务端回应rst+ack