ARTS-WEEK8

2019-05-13

本周ARTS

本周ARTS打卡内容:

  1. Algorithm 来源 LeetCode24
  2. Review 分享 Why I Love B2B over B2C
  3. Tip 分享 mysql的数据删除后恢复
  4. Share 分享 grpc-gateway

Algorithm

LeetCode的24题,调换链表中两个元素的位置:

https://leetcode.com/problems/swap-nodes-in-pairs/

例如,对于链表:

1
1->2->3->4

调换链表中每两个元素的位置后:

1
2->1->4->3

解题思路:

直接从1开始不好处理,所以我们在链表前面再加入一个元素0,即0->1->2->3->4,调换后链表中的元素应该是0指向2,2指向1,1指向3,然后从2开始按照同样的方法递推,直至遍历完链表,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func swapPairs(head *ListNode) *ListNode {
first := &ListNode{0, nil}
first.Next = head
var node1 , node2 , node3 *ListNode
node1 = first
for node1 != nil && node1.Next != nil && node1.Next.Next != nil {
node2 = node1.Next
node3 = node2.Next
node1.Next, node3.Next, node2.Next = node3, node2, node3.Next
node1 = node2
}
return first.Next
}

算法复杂度:

遍历了链表所有n个元素,所以算法的时间复杂度为O(n)。

Review

Why I Love B2B over B2C

作者在文中对比了B2C和B2B的特点:

  1. B2C是赌博而B2B是可控的。成功的B2C公司都是抓住了时代趋势,而趋势是不可预测的。比如Google抓住的早期互联网信息的浪潮,facebook抓住了互联网增长,人们需要线上身份和联系的浪潮,uber抓住了移动互联网浪潮。而B2B是可控的,解决企业的痛点。
  2. B2B消费者知道他们需要什么,而B2C产品的探索是在黑暗中摸索。
  3. B2C业务中,不知道是否有效,而B2B有明确的执行方向。
  4. B2C中的迭代是困难的,而B2B有明确的执行步骤。
  5. B2B用户将为你的产品付费。
  6. B2C的消费者容易对产品倦怠。
  7. 为了在B2C领域成功,解决你自己的问题。
  8. 结论:如果真的想做B2C,就去做吧。互联网成功的大公司都是面向消费者的,如果对B2C业务有热情,或者想尝试,就去做吧,但是如果失败,请尝试B2B。

Tip

在测试环境使用mysqldump导出数据:

1
mysqldump -u wams -p wams > wams.sql

导出了wams数据库的表。

然后把wams.sql文件拷贝到生产环境上导入:

1
mysql -u wams -p < wams.sql

测试环境的wams_info表被覆盖。

发现问题后,首先查看了mysql的日志文件,在/var/lib/mysql下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
root@2898e8d674fb:/var/lib/mysql# ls -ltr
total 192492
-rw-r----- 1 mysql mysql 50331648 Mar 29 01:31 ib_logfile1
drwxr-x--- 2 mysql mysql 4096 Mar 29 01:31 performance_schema
-rw-r----- 1 mysql mysql 56 Mar 29 01:31 auto.cnf
-rw------- 1 mysql mysql 1676 Mar 29 01:31 ca-key.pem
-rw-r--r-- 1 mysql mysql 1112 Mar 29 01:31 ca.pem
-rw------- 1 mysql mysql 1676 Mar 29 01:31 server-key.pem
-rw-r--r-- 1 mysql mysql 1112 Mar 29 01:31 server-cert.pem
-rw------- 1 mysql mysql 1680 Mar 29 01:31 client-key.pem
-rw-r--r-- 1 mysql mysql 1112 Mar 29 01:31 client-cert.pem
-rw-r--r-- 1 mysql mysql 452 Mar 29 01:31 public_key.pem
-rw------- 1 mysql mysql 1680 Mar 29 01:31 private_key.pem
drwxr-x--- 2 mysql mysql 4096 Mar 29 01:31 mysql
drwxr-x--- 2 mysql mysql 4096 Mar 29 01:31 sys
-rw-r----- 1 mysql mysql 3090087 Mar 29 01:32 binlog.000001
-rw-r----- 1 mysql mysql 3854 Mar 29 02:15 binlog.000002
-rw-r----- 1 mysql mysql 4731 Mar 29 02:15 ib_buffer_pool
drwxr-x--- 2 mysql mysql 4096 Mar 29 02:15 #innodb_temp
-rw-r----- 1 mysql mysql 48 Mar 29 02:15 binlog.index
-rw-r----- 1 mysql mysql 12582912 Mar 29 02:15 ibtmp1
drwxr-x--- 2 mysql mysql 4096 May 7 11:32 wams
-rw-r----- 1 mysql mysql 12582912 May 7 13:05 undo_001
-rw-r----- 1 mysql mysql 11261080 May 7 13:39 binlog.000003
-rw-r----- 1 mysql mysql 12582912 May 7 13:39 undo_002
-rw-r----- 1 mysql mysql 12582912 May 7 13:39 ibdata1
-rw-r----- 1 mysql mysql 31457280 May 7 13:39 mysql.ibd
-rw-r----- 1 mysql mysql 50331648 May 7 13:39 ib_logfile0

最新的日志文件为binlog.000003,需要注意的是文件的当前日期为数据库中的时间,可以在数据库中看到:

1
2
3
4
5
6
7
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2019-05-07 13:42:03 |
+---------------------+
1 row in set (0.00 sec)

将其拷贝出来用以恢复:

1
cp binlog.000003 /opt/backup/

解析二进制文件内容:

1
mysqlbinlog binlog.000003 > 0003.sql

报错:

1
mysqlbinlog: unknown variable 'default-character-set=utf8'

这个问题有两种解决办法:

  1. 加–no-defaults,即运行mysqlbinlog --no-defaults binlog.000003 > 0003.sql
  2. 在配置文件my.cnf中屏蔽掉#default-character-set=utf8

方法二需要重启,故现场使用方法一。

生成0003.sql文件后查看其内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#190329 2:15:29 server id 1 end_log_pos 124 CRC32 0x7944a725 Start: binlog v 4, server v 8.0.15 created 190329 2:15:29 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
wX+dXA8BAAAAeAAAAHwAAAABAAQAOC4wLjE1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADBf51cEwANAAgAAAAABAAEAAAAYAAEGggAAAAICAgCAAAACgoKKioAEjQA
CgElp0R5
'/*!*/;
# at 124
#190329 2:15:29 server id 1 end_log_pos 155 CRC32 0xb660587d Previous-GTIDs
# [empty]
# at 155
#190329 2:19:38 server id 1 end_log_pos 234 CRC32 0x48c3622a Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1553825978759534 immediate_commit_timestamp=1553825978759534 transaction_length=394
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1553825978759534 (2019-03-29 02:19:38.759534 UTC)
# immediate_commit_timestamp=1553825978759534 (2019-03-29 02:19:38.759534 UTC)
/*!80001 SET @@session.original_commit_timestamp=1553825978759534*//*!*/;
/*!80014 SET @@session.original_server_version=80015*//*!*/;
/*!80014 SET @@session.immediate_server_version=80015*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 234
#190329 2:19:38 server id 1 end_log_pos 309 CRC32 0xaf3cbfc7 Query thread_id=9 exec_time=0 error_code=0
SET TIMESTAMP=1553825978/*!*/;
SET @@session.pseudo_thread_id=9/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;

选择需要恢复到的位置运行:

1
mysqlbinlog --no-defaults binlog.000003  --start-position=4 --stop-position=1450410 > back.sql

其中start-position为起始位置,stop-position为需要恢复到的位置,position信息可以查看0003.sql文件中at后的数字。

恢复数据:

1
mysql -u root -p < back.sql

需要注意的是最好选择正确的恢复时间,若运行:

1
mysql -u root -p -f< 0003.sql

会把0003.sql中数据的变化重新演练一遍,最后恢复在日志记录的时间,加上-f强制执行,跳过主键的报错。

除了start-positionstop-position外,还可以使用start-datetimestop-datetime,但是时间格式最好正确,恢复过程中一直没找到正确的时间格式,所以最后选择了position。

另外在恢复过程中也选用了间隔很小的position,比如:

1
mysqlbinlog --no-defaults binlog.000003  --start-position=1450300 --stop-position=1450410 > back.sql

只恢复了1450300到1450410之间的数据变化。

Share

分享grpc-gateway,grpc-gateway能接收gRPC请求,也能接收http请求,将http请求转换为gRPC请求,调用后端的gRPC服务。

架构图如下:

image

项目地址:

https://github.com/grpc-ecosystem/grpc-gateway