查看表空间使用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT
a.TABLESPACE_NAME,
a.BYTES / 1024 / 1024 "Sum MB",
(a.BYTES - b.BYTES) / 1024 / 1024 "Used MB",
b.BYTES / 1024 / 1024 "free MB",
ROUND(((a.BYTES - b.BYTES) / a.BYTES) * 100, 2)
AS "percent_used"
FROM (SELECT
TABLESPACE_NAME,
SUM(BYTES) bytes
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) a,
(SELECT
TABLESPACE_NAME,
SUM(BYTES) bytes,
MAX(BYTES) largest
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) b
WHERE a.TABLESPACE_NAME = b.TABLESPACE_NAME
ORDER BY ((a.BYTES - b.BYTES) / a.BYTES) DESC

查询数据库高速缓冲区命中率

相关计算公式:1-(‘physical reads cache’/(‘db block gets from cache’ + ‘consistent gets from cache’))

1
2
select name, value from v$sysstat
where name in ('db block gets from cache', 'consistent gets from cache', 'physical reads cache');

查询命中率比较低的Sql(低效Sql)

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
PARSING_SCHEMA_NAME,
EXECUTIONS,
DISK_READS,
BUFFER_GETS,
ROUND((BUFFER_GETS - DISK_READS) / BUFFER_GETS, 2) Hit_radio,
ROUND(DISK_READS / EXECUTIONS, 2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS > 0
AND BUFFER_GETS > 0
AND (BUFFER_GETS - DISK_READS) / BUFFER_GETS < 0.8
ORDER BY 4 DESC;

找出总消耗时间最多的前10条语句

1
2
3
4
5
6
SELECT sql_id,child_number,sql_text, elapsed_time 
FROM (SELECT sql_id, child_number, sql_text, elapsed_time, cpu_time,
disk_reads,
RANK () OVER (ORDER BY elapsed_time DESC) AS elapsed_rank
FROM v$sql)
WHERE elapsed_rank <= 10

按等待时间排序等待事件

1
2
3
4
5
6
7
8
9
SELECT   wait_class, event, total_waits AS waits,
ROUND (time_waited_micro / 1000) AS total_ms,
ROUND (time_waited_micro * 100 / SUM (time_waited_micro) OVER (),
2
) AS pct_time,
ROUND ((time_waited_micro / total_waits) / 1000, 2) AS avg_ms
FROM v$system_event
WHERE wait_class <> 'Idle'
ORDER BY time_waited_micro DESC;

查询会话历史表中锁等待的Sql和对象

(最近一个小时左右), 可以将v$active_session_history替换为dba_hist_active_sess_history以显示更长时间范围内的等待对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH ash_query AS (
SELECT substr(event,6,2) lock_type,program,
h.module, h.action, object_name,
SUM(time_waited)/1000 time_ms, COUNT( * ) waits,
username, sql_text,
RANK() OVER (ORDER BY SUM(time_waited) DESC) AS time_rank,
ROUND(SUM(time_waited) * 100 / SUM(SUM(time_waited))
OVER (), 2) pct_of_time
FROM v$active_session_history h
JOIN dba_users u USING (user_id)
LEFT OUTER JOIN dba_objects o
ON (o.object_id = h.current_obj#)
LEFT OUTER JOIN v$sql s USING (sql_id)
WHERE event LIKE 'enq: %'
GROUP BY substr(event,6,2) ,program, h.module, h.action,
object_name, sql_text, username)
SELECT lock_type,module, username, object_name, time_ms,pct_of_time,
sql_text
FROM ash_query
WHERE time_rank < 11
ORDER BY time_rank;

查询遭遇最多行级锁等待的数据库对象

1
2
3
4
5
SELECT object_name, VALUE row_lock_waits, 
ROUND(VALUE * 100 / SUM(VALUE) OVER (), 2) pct
FROM v$segment_statistics
WHERE statistic_name = 'row lock waits' AND VALUE > 0
ORDER BY VALUE DESC;

查询锁的持有者和等待获取锁的会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 WITH sessions AS 
(SELECT /*+ materialize*/ username,sid,sql_id
FROM v$session),
locks AS
(SELECT /*+ materialize */ *
FROM v$lock)
SELECT l2.type,s1.username blocking_user, s1.sid blocking_sid,
s2.username blocked_user, s2.sid blocked_sid, sq.sql_text
FROM locks l1
JOIN locks l2 USING (id1, id2)
JOIN sessions s1 ON (s1.sid = l1.sid)
JOIN sessions s2 ON (s2.sid = l2.sid)
LEFT OUTER JOIN v$sql sq
ON (sq.sql_id = s2.sql_id)
WHERE l1.BLOCK = 1 AND l2.request > 0

查询消耗PGA内存最多的5个进程

查询消耗PGA内存最多的5个进程和当前正在执行的Sql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
WITH pga AS 
(SELECT sid,
ROUND(SUM(CASE name WHEN 'session pga memory'
THEN VALUE / 1048576 END),2) pga_memory_mb,
ROUND(SUM(CASE name WHEN 'session pga memory max'
THEN VALUE / 1048576 END),2) max_pga_memory_mb
FROM v$sesstat
JOIN v$statname USING (statistic#)
WHERE name IN ('session pga memory','session pga memory max' )
GROUP BY sid)
SELECT sid, username,s.module,
pga_memory_mb,
max_pga_memory_mb, substr(sql_text,1,70) sql_text
FROM v$session s
JOIN (SELECT sid, pga_memory_mb, max_pga_memory_mb,
RANK() OVER (ORDER BY pga_memory_mb DESC) pga_ranking
FROM pga)
USING (sid)
LEFT OUTER JOIN v$sql sql
ON (s.sql_id=sql.sql_id and s.sql_child_number=sql.child_number)
WHERE pga_ranking <=5
ORDER BY pga_ranking

合并PGA+SGA的内存顾问适用于11g

Combined (PGA+SGA) memory advice report for 11g

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
WITH db_cache_times AS 
(SELECT current_size current_cache_mb,
size_for_estimate target_cache_mb,
(estd_physical_read_time - current_time)
cache_secs_delta
FROM v$db_cache_advice,
(SELECT size_for_estimate current_size,
estd_physical_read_time current_time
FROM v$db_cache_advice
WHERE size_factor = 1
AND name = 'DEFAULT' AND block_size = 8192)
WHERE name = 'DEFAULT' AND block_size = 8192),
pga_times AS
(SELECT current_size / 1048576 current_pga_mb,
pga_target_for_estimate / 1048576 target_pga_mb,
estd_time-base_time pga_secs_delta
FROM v$pga_target_advice ,
(SELECT pga_target_for_estimate current_size,
estd_time base_time
FROM v$pga_target_advice
WHERE pga_target_factor = 1))
SELECT current_cache_mb||'MB->'||target_cache_mb||'MB' Buffer_cache,
current_pga_mb||'->'||target_pga_mb||'MB' PGA,
pga_secs_delta,cache_secs_delta,
(pga_secs_delta+cache_secs_delta) total_secs_delta
FROM db_cache_times d,pga_times p
WHERE (target_pga_mb+target_cache_mb)
<=(current_pga_mb+current_cache_mb)
AND (pga_secs_delta+cache_secs_delta) <0
ORDER BY (pga_secs_delta+cache_secs_delta);

执行结果
BUFFER_CACHE PGA PGA_SECS_DELTA CACHE_SECS_DELTA TOTAL_SECS_DELTA


1760MB->2288MB 1120->560MB 0 -2008 -2008
1760MB->2112MB 1120->560MB 0 -1612 -1612
1760MB->1936MB 1120->560MB 0 -901 -901
1760MB->1936MB 1120->840MB 0 -901 -901
结果分析:给高速缓存区增加528MB(2288MB-1760MB)内存可以节约2008秒的时间。减少PGA内存560MB(1120MB-560MB)未受到影响。

查询显示PGA内存管理方式

1
2
3
--alter system set workarea_size_policy=manual; --将pga内存管理设置为手动管理
--alter system set workarea_size_policy=auto; --将pga内存管理设置为自动管理
show parameter workarea_size_policy;

NAME TYPE VALUE


workarea_size_policy string AUTO
值为AUTO时表示自动管理,为MANUAL是表示手动管理

查询数据库中子表上没有索引的外键

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
SELECT c.owner,
c.constraint_name,
c.table_name,
cc.column_name,
c.status
FROM dba_constraints c, dba_cons_columns cc
WHERE c.constraint_type = 'R'
AND c.owner NOT IN
('SYS',
'SYSTEM',
'SYSMAN',
'EXFSYS',
'WMSYS',
'OLAPSYS',
'OUTLN',
'DBSNMP',
'ORDSYS',
'ORDPLUGINS',
'MDSYS',
'CTXSYS',
'AURORA$ORB$UNAUTHENTICATED',
'XDB',
'FLOWS_030000',
'FLOWS_FILES')
AND c.owner = cc.owner
AND c.constraint_name = cc.constraint_name
AND NOT EXISTS
(SELECT 'x'
FROM dba_ind_columns ic
WHERE cc.owner = ic.table_owner
AND cc.table_name = ic.table_name
AND cc.column_name = ic.column_name
AND cc.position = ic.column_position
AND NOT EXISTS
(SELECT owner, index_name
FROM dba_indexes i
WHERE i.table_owner = c.owner
AND i.index_Name = ic.index_name
AND i.owner = ic.index_owner
AND (i.status = 'UNUSABLE'
OR i.partitioned = 'YES'
AND EXISTS
(SELECT 'x'
FROM dba_ind_partitions ip
WHERE status =
'UNUSABLE'
AND ip.
index_owner =
i.
owner
AND ip.
index_Name =
i.
index_name
UNION ALL
SELECT 'x'
FROM dba_ind_subpartitions isp
WHERE status =
'UNUSABLE'
AND isp.
index_owner =
i.
owner
AND isp.
index_Name =
i.
index_name))))
ORDER BY 1, 2

使用EntLib的Log组件记录日志时,经常有这样的需求,需要将日志记录到数据库中方便查询。但实际使用时经常会遇到网络问题或数据库端异常等原因,导致无法准确定位问题所在。出现这种情况时,需要将日志记录到本地文件中进行排查。
EntLib中的Log组件,使用监听器(Listener)的方式对日志进行分类记录。使用Listener时有顺序要求,假设有两个Listener,Database Trace Listener用于将日志记录到数据库中,Rolling Flat File Trace Listener将日志写入到文件中。
如果前一个Database Trace Listener不起作用或者执行过程中出现异常,后一个的Rolling Flat File Trace Listener也将不会执行。

假设你使用了自定义分类,还有一种可能原因是没有配置categorySources的子节点。
eg. 在记录日志时指定的分类为Program, 则必须在配置节点中添加如下配置:

1
2
3
4
5
6
7
8
<categorySources>
<add switchValue="All" name="Program">
<listeners>
<add name="Formatted EventLog TraceListener"/>
<add name="Rolling Flat File Trace Listener"/>
</listeners>
</add>
</categorySources>

LogEntry类用于封装传递需要记录的日志信息。LogEntry包含一个类型为IDictionary<string, object>的属性ExtendedProperties.使用时需要注意的是,字典的类型Value类型为object, 但建议往其中写入值时最好保存为string类型。因为每个Lintener都需要指定一个格式化器(Formatter),可以Formatter中指定显示内容,在显示ExtendedProperties中的Value值时可能不支持对应的object转换为string.

20170505 Update
在项目中引入Database Trace Listener时,也有可能造成无法记录日志


可能原因是:Microsoft.Practices.EnterpriseLibrary.Logging.Database.dll没拷贝到对应的bin或程序根目录中,导致引用查找Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData时抛出异常: A configuration error has occurred.

20170928 Update
在使用Database Trace Listener时内部调用的存储过程出错也会造成无日志的bug. 这个bug有点难排查,如果存储过程调用失败,Windows事件记录中也没有相关记录。
排查记录过程:发现日志表T_SYS_LOG_INFO多了一个字段,而存储过程Write_Log中内容是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
--Oracle存储过程
create or replace procedure Write_Log(
EventID INTEGER,
Priority INTEGER,
Severity NVARCHAR2,
Title NVARCHAR2,
Timestamp DATE,
MachineName NVARCHAR2,
AppDomainName NVARCHAR2,
ProcessID NVARCHAR2,
ProcessName NVARCHAR2,
ThreadName NVARCHAR2,
Win32ThreadId NVARCHAR2,
Message NVARCHAR2,
FormattedMessage NVARCHAR2,
LogId out INTEGER) is
v_ID INTEGER;
begin
SELECT SEQ_T_SYS_LOG_INFO.NEXTVAL INTO v_ID FROM DUAL;
INSERT INTO T_SYS_LOG_INFO
VALUES(v_ID, EventID, Priority, Severity, Title, Timestamp, MachineName, AppDomainName, ProcessID, ProcessName, ThreadName, Win32ThreadId, Message, FormattedMessage);
SELECT v_ID INTO LogId FROM DUAL;
end Write_Log;

添加的列中无默认值,导致在调用这个存储过程时,存储过程中的sql执行失败。修改存储过程INSERT语句,指定列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--Oracle存储过程
create or replace procedure Write_Log(
EventID INTEGER,
Priority INTEGER,
Severity NVARCHAR2,
Title NVARCHAR2,
Timestamp DATE,
MachineName NVARCHAR2,
AppDomainName NVARCHAR2,
ProcessID NVARCHAR2,
ProcessName NVARCHAR2,
ThreadName NVARCHAR2,
Win32ThreadId NVARCHAR2,
Message NVARCHAR2,
FormattedMessage NVARCHAR2,
LogId out INTEGER) is
v_ID INTEGER;
begin
SELECT SEQ_T_SYS_LOG_INFO.NEXTVAL INTO v_ID FROM DUAL;
INSERT INTO T_SYS_LOG_INFO
(ID, EVENT_ID, PRIORITY, SEVERITY, TITLE, TIMESTAMP, MACHINE_NAME, APPDOMAIN_NAME, PROCESS_ID, PROCESS_NAME, THREAD_NAME, WIN32_THREAD_ID, MESSAGE, FORMATTED_MESSAGE)
VALUES(v_ID, EventID, Priority, Severity, Title, Timestamp, MachineName, AppDomainName, ProcessID, ProcessName, ThreadName, Win32ThreadId, Message, FormattedMessage);
SELECT v_ID INTO LogId FROM DUAL;
end Write_Log;

需要将Oracle中的数据进行导入导出时,可以使用imp和exp命令进行操作。exp命令可以将数据库服务器端的数据导出到本地的.dmp文件中,而imp命令可以将.dmp文件中的数据还原到数据库中。
如果不了解详细的命令参数,可以使用exp help=y,imp help=y进行查询。

数据导出导入示例

数据导出.bat

1
2
exp 用户名/密码 file='文件绝对路径.dmp' filesize=10G tables=数据表1,数据表2,数据表3 grants=n indexes=n triggers=n record=n constraints=n rows=y feedback=10000
pause;

文件导入.bat
1
2
imp 用户名/密码 file='文件绝对路径.dmp' tables=数据表1,数据表2,数据表3 DATA_ONLY=y
pause;

exp相关参数

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
C:\Users\Administrator>exp help=y

Export: Release 11.2.0.1.0 - Production on 星期四 6月 16 10:02:16 2016

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.



通过输入 EXP 命令和您的用户名/口令, 导出
操作将提示您输入参数:

例如: EXP SCOTT/TIGER

或者, 您也可以通过输入跟有各种参数的 EXP 命令来控制导出
的运行方式。要指定参数, 您可以使用关键字:

格式: EXP KEYWORD=value 或 KEYWORD=(value1,value2,...,valueN)
例如: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR)
或 TABLES=(T1:P1,T1:P2), 如果 T1 是分区表

USERID 必须是命令行中的第一个参数。

关键字 说明 (默认值) 关键字 说明 (默认值)
--------------------------------------------------------------------------
USERID 用户名/口令 FULL 导出整个文件 (N)
BUFFER 数据缓冲区大小 OWNER 所有者用户名列表
FILE 输出文件 (EXPDAT.DMP) TABLES 表名列表
COMPRESS 导入到一个区 (Y) RECORDLENGTH IO 记录的长度
GRANTS 导出权限 (Y) INCTYPE 增量导出类型
INDEXES 导出索引 (Y) RECORD 跟踪增量导出 (Y)
DIRECT 直接路径 (N) TRIGGERS 导出触发器 (Y)
LOG 屏幕输出的日志文件 STATISTICS 分析对象 (ESTIMATE)
ROWS 导出数据行 (Y) PARFILE 参数文件名
CONSISTENT 交叉表的一致性 (N) CONSTRAINTS 导出的约束条件 (Y)

OBJECT_CONSISTENT 只在对象导出期间设置为只读的事务处理 (N)
FEEDBACK 每 x 行显示进度 (0)
FILESIZE 每个转储文件的最大大小
FLASHBACK_SCN 用于将会话快照设置回以前状态的 SCN
FLASHBACK_TIME 用于获取最接近指定时间的 SCN 的时间
QUERY 用于导出表的子集的 select 子句
RESUMABLE 遇到与空格相关的错误时挂起 (N)
RESUMABLE_NAME 用于标识可恢复语句的文本字符串
RESUMABLE_TIMEOUT RESUMABLE 的等待时间
TTS_FULL_CHECK 对 TTS 执行完整或部分相关性检查
TABLESPACES 要导出的表空间列表
TRANSPORT_TABLESPACE 导出可传输的表空间元数据 (N)
TEMPLATE 调用 iAS 模式导出的模板名

成功终止导出, 没有出现警告。

imp相关参数

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
C:\Users\Administrator>imp help=y

Import: Release 11.2.0.1.0 - Production on 星期四 6月 16 10:22:54 2016

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.



通过输入 IMP 命令和您的用户名/口令, 导入
操作将提示您输入参数:

例如: IMP SCOTT/TIGER

或者, 可以通过输入 IMP 命令和各种参数来控制导入
的运行方式。要指定参数, 您可以使用关键字:

格式: IMP KEYWORD=value 或 KEYWORD=(value1,value2,...,valueN)
例如: IMP SCOTT/TIGER IGNORE=Y TABLES=(EMP,DEPT) FULL=N
或 TABLES=(T1:P1,T1:P2), 如果 T1 是分区表

USERID 必须是命令行中的第一个参数。

关键字 说明 (默认值) 关键字 说明 (默认值)
--------------------------------------------------------------------------
USERID 用户名/口令 FULL 导入整个文件 (N)
BUFFER 数据缓冲区大小 FROMUSER 所有者用户名列表
FILE 输入文件 (EXPDAT.DMP) TOUSER 用户名列表
SHOW 只列出文件内容 (N) TABLES 表名列表
IGNORE 忽略创建错误 (N) RECORDLENGTH IO 记录的长度
GRANTS 导入权限 (Y) INCTYPE 增量导入类型
INDEXES 导入索引 (Y) COMMIT 提交数组插入 (N)
ROWS 导入数据行 (Y) PARFILE 参数文件名
LOG 屏幕输出的日志文件 CONSTRAINTS 导入限制 (Y)
DESTROY 覆盖表空间数据文件 (N)
INDEXFILE 将表/索引信息写入指定的文件
SKIP_UNUSABLE_INDEXES 跳过不可用索引的维护 (N)
FEEDBACK 每 x 行显示进度 (0)
TOID_NOVALIDATE 跳过指定类型 ID 的验证
FILESIZE 每个转储文件的最大大小
STATISTICS 始终导入预计算的统计信息
RESUMABLE 在遇到有关空间的错误时挂起 (N)
RESUMABLE_NAME 用来标识可恢复语句的文本字符串
RESUMABLE_TIMEOUT RESUMABLE 的等待时间
COMPILE 编译过程, 程序包和函数 (Y)
STREAMS_CONFIGURATION 导入流的一般元数据 (Y)
STREAMS_INSTANTIATION 导入流实例化元数据 (N)
DATA_ONLY 仅导入数据 (N)

下列关键字仅用于可传输的表空间
TRANSPORT_TABLESPACE 导入可传输的表空间元数据 (N)
TABLESPACES 将要传输到数据库的表空间
DATAFILES 将要传输到数据库的数据文件
TTS_OWNERS 拥有可传输表空间集中数据的用户

成功终止导入, 没有出现警告。

在Mvc 3项目中老是出现“使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength 属性设置的值。”的异常信息。
查询Google之后找到解决方案如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public ContentResult GetResult()
{
var obj = new object();
var serializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue, RecursionLimit = 3 };

var jsonResult = new ContentResult()
{
Content = serializer.Serialize(obj),
ContentType = "application/json"
};

return jsonResult;
}

另外还可以通过自定义JsonReuslt的方式解决这个异常, 具体做法参考这个链接:https://brianreiter.org/2011/01/03/custom-jsonresult-class-for-asp-net-mvc-to-avoid-maxjsonlength-exceeded-exception/

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Install Hexo

1
2
3
npm install -g hexo-cli

hexo -v

Create a new post

1
$ hexo new "My New Post"

用new命令创建文章时,会将中间空格替换为横杠-,上述命令最终生成文件名为:”My-New-Post.md”. 创建时可以不用包含双引号,生成的文件取的最后一个单词,例如:hexo new how to use google,命令生成的文件为:google.md.
创建时最好使用英文,英文相对中文来说生成的Url更友好些。
More info: Writing

Run server

1
$ hexo server

More info: Server

Clean

1
$ hexo clean

clean命令用于清除publish文件中已经生成的文件和清除缓存文件。

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

Deploy前需要安装hexo-deployer-git插件
npm install hexo-deployer-git –save
删除本地存在的.deploy_git
将远程的git仓库克隆到本地
git clone https://github.com/yuanrui/yuanrui.github.io.git .deploy_git
同时需要配置_config.yml文件中deploy设置
注意:冒号后面需要有空格!!!坑

1
2
3
4
5
6
7
8
9
10
11
12
deploy:
type: git
repo:
#github: git@github.com:yuanrui/yuanrui.github.io.git
github: https://github.com/yuanrui/yuanrui.github.io.git
branch: master
name: yuanrui
```

发布时使用
``` bash
$ hexo deploy

More info: Deployment

安装插件

安装Rss插件

1
npm install hexo-generator-feed --save

安装github-card插件
1
npm install hexo-github-card

参考:
http://www.jianshu.com/p/ba76165ca84d
https://gist.github.com/yuanrui/1a32715d562c6b2b8ac00a7a91958dc7

TODO