news 2026/10/7 8:58:33

SAP HANA 2.0 Express 学习环境搭建全攻略:从虚拟机配置到跑通第一条SQL

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SAP HANA 2.0 Express 学习环境搭建全攻略:从虚拟机配置到跑通第一条SQL

看到这个标题,我第一反应就是又有人要入 SAP HANA 2.0 这个坑了。实际上,HANA 这块的“劝退点”往往不在数据库本身,而在学习环境搭建这第一步:官方文档看完一头雾水,虚拟机配置不知道给多少,安装过程中报错又不知道该查哪里。我自己前后搭过不下十套 HANA 2.0 的学习环境,从笔记本上的虚拟机到独立服务器都折腾过,踩坑踩出了经验。这篇文章就把整套流程完整拆开,从选版本、准备虚拟机、执行安装到接客户端跑通第一条 SQL,按顺序讲清楚,同时把安装中容易翻车的地方一并列出来。不管你是刚接触 HANA 的运维新人,还是想自己搭一套环境来做 ABAP 或数据分析开发的,这篇文章都应该能帮你少走很多弯路。

1. 搭建前的思路整理:为什么选择 HANA 2.0 Express

1.1 Express 版本与传统版本的区别

SAP HANA 2.0 严格来说是个平台概念,下面分好几个版本。企业生产环境用的是 SAP HANA Platform Edition,走的是商业授权;而个人学习、开发、测试用的版本叫 SAP HANA 2.0 Express Edition,也就是社区常说的 HXE。这两者在核心引擎上是同源的,SQL 语法、行存列存、建模逻辑基本一致,区别主要体现在授权模式、节点扩展能力和部分高级功能。

Express 版本是 SAP 官方专门放出来给开发者用的免费版本,免费是有前提的:你的物理机内存不能超过 32GB(某些版本限制为 16GB),超过的话商业授权会限制你使用。这规则对学习来说其实很够用,你拿一台 16GB 内存的笔记本跑虚拟机完全在允许范围内。HXE 还附带 XSA(Extended Application Services Advanced),可以跑 Node.js 和 Java 应用,做小规模的业务建模和开发验证非常合适。

我实际用下来的感觉是:如果你只是想把 HANA 跑起来,学习 SQL、学习列存储机制、练习数据建模,Express 版和企业版之间的差异对你的学习几乎没有影响。反过来说,如果你一上来就想着搭集群、搞高可用,那 Express 版确实不合适,这是学习环境不该碰的场景。

1.2 虚拟机配置到底该给多少资源

HANA 是内存计算数据库,配置的核心就是内存。SAP 官方的安装文档里明确写着一个最低要求:至少 8GB 内存。但请注意,这个 8GB 是指 HANA 数据库进程可用的内存,不是你的虚拟机总内存。我测试过多次,如果虚拟机只分配 8GB 内存,装完 HANA 后系统几乎跑不动,XSA 服务也可能因为内存不够直接起不来。

我的经验值是:宿主机至少 16GB 内存,虚拟机分配 10-12GB;如果宿主机内存能到 32GB,虚拟机给 16GB 会比较舒服。CPU 方面 2 核是底线,4 核更顺畅,我实际装的时候用的是 4 核,HANA 编译建模任务时明显更跟手。磁盘空间至少留 100GB,HANA 的数据卷、日志卷以及 XSA 的依赖安装包会吃掉相当多空间,加上 SUSE 系统本身,80GB 会比较紧张。

还有一点容易被忽略:Swap 交换分区。内存不足时 Swap 可以兜底,但 HANA 不会主动把内存页换出去,所以 Swap 起的是保护作用而不是扩容作用。我给学习环境配置的是 32GB Swap,这样在内存吃紧时不会直接触发 OOM 把数据库杀掉。

1.3 两条安装路线对比:OVA 镜像还是手动装系统

SAP 官方为 HANA 2.0 Express 提供两种安装介质。一种是完整的服务器镜像(.iso),需要你先装好 SUSE Linux Enterprise Server 12/15,再手动运行安装脚本;另一种是官方做好的虚拟机镜像(.ova),里面已经把 SUSE 系统、HANA 2.0 Express、XSA 全部预装妥当,你只需要导入虚拟机、开机、做基础配置就可以直接用。

这里我的建议非常明确:学习环境优先选 OVA 镜像。原因有三个。第一,手动装 SUSE 再装 HANA,中间涉及大量系统依赖,比如 libstdc++、图形界面库、主机名配置等,任何一个环节出问题都会浪费大量时间。第二,OVA 镜像里官方已经处理好了版本兼容性,你拿 .iso 手动装的时候如果某次驱动或内核版本不匹配,报错会相当难排查。第三,OVA 导入后只需要做网络配置、改密码、启动服务,整体不超过半小时。

我自己最初就是拿 .iso 硬装的,说实话能装成功,但光折腾系统依赖就花了两个晚上。后来用 OVA 装,整个过程行云流水。所以这篇文章后续的步骤我会以 OVA 路线为主,手动安装的差异点会在对应位置标出来。

2. 前置准备工作:把环境准备好再动手

2.1 下载与版本核对

先去 SAP Developers 官网找到 SAP HANA 2.0 Express Edition 的下载页面,注册一个免费的开发者账号就能下载。下载文件通常是一个名为 hxe.ova 的文件,体积在 2GB 到 3GB 之间,具体取决于版本号。下载的时候留意文件完整性,我遇到过下载过程中文件损坏导致导入虚拟机时报错的情况,所以推荐下载完比对一下官方给出的 SHA-256 校验值。

版本上需要留个心:HANA 2.0 Express 有 SPS 版本区分,SPS 03、SPS 04、SPS 05 之类,不同版本之间的安装脚本和默认配置有些微差别。下载时优先选择最新的 SPS 版本即可,功能更全,官方文档覆盖也更多。我自己用的是 SPS 05 版本,配置上多了些容器管理方面的改进,整体更稳定。

下载完成后,确认你的虚拟化软件。Windows 上我推荐 VMware Workstation Pro,macOS 上可以用 VMware Fusion,免费方案也有 VirtualBox 但 OVA 导入时偶尔会出现虚拟硬件兼容性问题。VMware 系列对 OVA 的支持最成熟,直接“文件 -> 打开”就能导入。

2.2 导入虚拟机镜像

将 hxe.ova 导入 VMware 的步骤不复杂,但有几个点需要注意。导入时虚拟机的名称可以自定义,比如我就习惯命名为 HXE-2.0,这样好识别。存储路径不要放在 C 盘系统盘,HANA 的虚拟机磁盘文件动辄几十 GB,放在系统盘很容易把开发机磁盘撑满,建议放到剩余空间较大的数据盘。

导入完成后先不要开机,先编辑虚拟机设置。把内存调整到 10GB 以上,CPU 给到 4 核,然后检查硬盘大小。OVA 默认的虚拟磁盘是 100GB 左右,如果宿主机空间充裕,可以考虑扩展到 120GB,给自己留些余量。VMware 里扩展虚拟磁盘需要在关机状态下操作,扩展后还要进系统里用分区工具把新增空间添加进去。

这里我要强调网络适配器的选择,默认 NAT 模式就行。NAT 模式下宿主机和虚拟机之间可以互相访问,虚拟机也能访问外网,对学习环境来说足够。桥接模式也可以,但需要 DHCP 网络环境,否则还要手动配 IP,多一层麻烦。NAT 的好处是宿主机 IP 固定,后续配置客户端连接时不容易迷惑。

2.3 系统初始化与安装前检查

虚拟机开机后,会进入一个无人值守的初始化流程。第一次启动时,系统会自动检测硬件资源并生成对应的配置。这个阶段需要创建 SUSE 系统的 root 密码,以及 HANA 数据库系统用户(hxeadm)的密码,一定要记住这两个密码,后面所有运维操作几乎都要用到。

初始化完成后,建议先通过 SSH 登录到虚拟机,执行以下命令做一次基本体检:

# 查看系统内存 free -h # 查看磁盘空间 df -h # 查看主机名 hostname # 查看系统版本 cat /etc/os-release

第一次 SSH 登录时,用 root 账户连上去,密码就是刚才设置的 root 密码。这里有个常见坑:SUSE 系统默认禁用了 root 的 SSH 密码登录。如果 SSH 登录失败提示 Permission denied,可以到虚拟机控制台用 root 登录后,修改 /etc/ssh/sshd_config 文件,把 PermitRootLogin 改为 yes,然后重启 sshd 服务。这是一个非常典型的初始化问题,遇到别慌,改一下就好。

安装前最后一个检查项是 /etc/hosts 文件。HANA 对主机名解析非常敏感,主机名无法解析会导致安装脚本直接报错。检查命令是:

cat /etc/hosts

确保里面有一行类似127.0.0.1 hxehost.local hxehost的记录,其中 hxehost 是这台机器的主机名。如果没有,手动加上这一行。这一步不做,后面安装时大概率会卡在主机名解析上。

3. HANA 2.0 安装全流程实录

3.1 安装脚本启动与参数填写

OVA 镜像开箱后,HANA 数据库本体其实已经安装在系统里,但还需要运行一次配置脚本来完成实例初始化。登录 root 用户,切换到 hxeadm 用户,然后执行:

su - hxeadm cd /usr/sap/HXE/HDB90

接着运行安装配置脚本:

hdblcm --action=install

这个命令会进入交互式安装界面。如果 SSH 终端不支持图形界面,脚本会自动切换到文本模式,一样可以操作。安装界面会依次询问以下参数:

  • 安装类型:选择 install new system
  • 数据库隔离:学习环境选 single container 或 multiple container 都可以,我选 multiple container,更接近企业环境的结构
  • SID:默认是 HXE,保持默认即可
  • 实例号:默认是 90,保持默认
  • 主机名:自动识别,一般不用改
  • SYSTEM 用户密码:这是 HANA 数据库超级管理员的密码,必须满足复杂度要求

需要特别说明密码规则:HANA 2.0 的密码至少 8 位,必须包含大写字母、小写字母和数字,最好再加一个特殊字符。纯粹用简单密码会被直接打回。这里我踩过一次坑,刚开始设的密码过于简单,安装脚本反复提示密码不符合策略,后来老老实实换成了带符号的长密码才通过。

参数填写完成后,安装脚本会打印出即将执行的配置项,确认无误后开始执行。整个初始化过程大约需要 15 到 30 分钟,主要取决于 CPU 和磁盘性能。期间屏幕会滚动大量日志信息,不用紧张,只要没有出现 ERROR 级别的报错就属于正常。

3.2 安装中需要注意的细节

安装过程有几个细节值得单独拿出来说。第一个是根目录磁盘空间,HANA 初始化时会创建大量的数据文件和日志文件,如果 / 目录空间不足,安装过程会中途失败。我第二次装的时候就碰到过,OVA 默认的 LVM 分区给得比较保守,/var 和 /hana 目录在同一个卷组里,磁盘大小 100GB 按理说够用,但安装过程中 JVM 组件(用于 XSA)还会额外占用近 2GB 空间,所以预留空间宁多勿少。

第二个细节是 XSA 的初始化。XSA 是 HANA 的扩展应用服务,相当于在数据库之上跑了一层应用容器。安装时脚本会询问是否启用 XSA,学习环境建议启用。原因是 XSA 带了很多 HANA 开发所需的典型场景,比如通过 xs 命令行访问 HANA 的 Web IDE,未来学习基于 HANA 的应用开发会非常方便。

不过 XSA 是一个内存杀手,它启动时会占用额外的 2 到 3GB 内存。如果虚拟机内存只有 8GB,XSA 可能会启动失败。这时候可以考虑先不启用 XSA,等以后内存升级或优化后再启用。但这个决策最好在安装前想清楚,因为后续启用 XSA 需要重新运行配置脚本,会多花一些时间。

第三个细节是安装日志的位置。安装过程中生成的日志默认保存在 /var/tmp 目录下,如果安装失败,先去看这个目录下的日志,比在网上瞎搜报错信息高效得多。日志文件名通常会包含 hdblcm 字样,可以用下面的命令快速找到:

ls -lt /var/tmp/ | head -20

3.3 安装验证:数据库能不能起来

安装完成后,先用最简单的方式验证 HANA 进程是否正常。以 hxeadm 用户登录,执行命令:

HDB info

如果输出列出了 hdbnameserver、hdbcompileserver、hdbwebdispatcher 等进程,并且状态为 running,说明数据库实例已经启动。接着用 hdbsql 连接数据库实际执行一条查询,确认 SQL 层面没有问题:

hdbsql -U SYSTEM -d SYSTEMDB "select * from m_database"

这里的 -U SYSTEM 是使用安装时自动生成的 userstore 密钥,不需要手动输入密码。如果这条命令能返回一行记录,包含数据库名称、版本号、启动时间等信息,说明 HANA 已经完全可用了。

到这里,一套最小可用的 HANA 2.0 学习环境就已经搭好。看到这个结果,你其实已经完成了最重要的一步。接下来要做的核心工作是把外部开发工具接进来,真正把它用起来。

4. 开发与学习环境的连接与配置

4.1 客户端工具选择与连接串配置

HANA 数据库本体跑起来了,接下来要解决的问题是怎么连。官方推荐的客户端工具是 SAP HANA Studio,这是基于 Eclipse 的工具,适合做数据建模和数据库管理。不过 HANA Studio 的下载和安装相对繁琐,需要从 Eclipse 插件仓库在线安装,网络不好的时候能装到你怀疑人生。我的建议是把 HANA Studio 作为备选,主力客户端先用两个更轻量的工具。

第一个是 DBeaver,这是一款开源的通用数据库客户端,社区版就支持 SAP HANA 驱动,下载安装后只需要填连接参数就能用。第二个是官方命令行工具 hdbsql,它是最可靠的兜底方案,HANA 装好后自带的命令,任何图形界面出问题,hdbsql 都能帮你完成大部分操作。

连接 HANA 的关键参数有三项:主机 IP、端口号、租户库名。OVA 默认的 HANA 实例号是 90,对应的 SQL 端口是 3 + 实例号 + 13,也就是 39013。第一次连的时候要特别注意:如果你直接连 39013 端口,默认进入的是 SYSTEMDB(系统数据库)。企业环境下,业务数据通常放在 TENANTDB 租户数据库里。学习环境里,直接在 SYSTEMDB 上建 schema 跑 SQL 问题不大,但为了贴合企业习惯,建议尽快手动创建一个租户库。

DBeaver 的连接串配置如下:

主机:虚拟机IP,例如 192.168.56.101 端口:39013 数据库:SYSTEMDB 用户名:SYSTEM 密码:安装时设置的 SYSTEM 密码

JDBC URL 长这样:jdbc:sap://192.168.56.101:39013。配置完成后测试连接,能通就说明客户端接入成功。

4.2 防火墙与端口开放

外部客户端连不上 HANA,十有八九是防火墙的锅。SUSE 系统默认的防火墙是 SuSEfirewall2,在虚拟机里装 HANA 后,需要把 HANA 相关的端口放行,否则宿主机访问不到数据库。

学习环境为了省事,可以直接关闭防火墙:

systemctl stop SuSEfirewall2 systemctl disable SuSEfirewall2

如果你对系统安全比较在意,不想关闭防火墙,那就按需放行端口。HANA 需要开放的端口比较多,最常用的包括 39013(SQL)、39015(内部通信)、39017(Web Dispatcher)、39041(XS 经典)、8000(XSA HTTP)。放行命令如下:

iptables -A INPUT -p tcp --dport 39013 -j ACCEPT iptables -A INPUT -p tcp --dport 39015 -j ACCEPT iptables -A INPUT -p tcp --dport 39017 -j ACCEPT iptables -A INPUT -p tcp --dport 39041 -j ACCEPT

这里我必须提醒一句:学习环境里的 HANA 数据往往不重要,但 HANA 监听的端口一旦暴露到公网,被扫描到后会有一堆暴力破解尝试。所以虚拟机网络设置务必保持 NAT 模式,不要在生产网络里直连。

放行端口后,在宿主机上用 telnet 或 nc 测试连通性:

nc -vz 192.168.56.101 39013

输出显示 Connection succeeded,就说明端口通了,客户端可以正常连接。

4.3 建库建表跑通第一条 SQL

连接成功后,先建一个测试用户和 schema,模拟真实的开发场景。在 DBeaver 或 hdbsql 中执行:

-- 创建一个测试用户 CREATE USER DEVUSER IDENTIFIED BY "User1234"; -- 创建 schema 并授权 CREATE SCHEMA DEVSCHEMA; ALTER USER DEVUSER SET SCHEMA DEVSCHEMA; GRANT ALL PRIVILEGES ON SCHEMA DEVSCHEMA TO DEVUSER; -- 在 schema 下建表 CREATE COLUMN TABLE DEVSCHEMA.SALES ( ID INTEGER PRIMARY KEY, PRODUCT NVARCHAR(50), QUANTITY INTEGER, AMOUNT DECIMAL(10,2) );

注意 HANA 和传统数据库一个显著区别:默认建表通常是列存储表,用CREATE COLUMN TABLE显式声明。HANA 的核心优势就是列式存储和内存计算,学习时尽量用列存表,体验一下和行存表的差异。

导入几条简单的数据后,就可以跑查询了:

INSERT INTO DEVSCHEMA.SALES VALUES (1, '笔记本', 3, 15000.00); INSERT INTO DEVSCHEMA.SALES VALUES (2, '显示器', 5, 8000.00); SELECT PRODUCT, SUM(AMOUNT) AS TOTAL_AMOUNT FROM DEVSCHEMA.SALES GROUP BY PRODUCT;

到这里,一套从数据库搭建到客户端接入、再到执行 SQL 的完整闭环就已经打通了。接下来所有后续操作,比如导入业务数据、做报表建模、学习 HANA 的各类 SQL 扩展,都是在这个基础之上进行的。

5. 常见故障与日常维护速查

5.1 安装卡住、内存不足的典型处理方法

安装 HANA 时最容易碰到的就是内存不足问题。HANA 安装脚本在启动时就会检查系统可用内存,低于物理机 8GB 会直接报错,这和我前面强调的 10GB 以上虚拟机内存相呼应。但还有一种情况是:你的虚拟机内存供应商给了 16GB,但在安装过程中还是出现内存分配失败的日志。

这类问题多半是 HANA 的全局内存分配策略导致的。HANA 会自动探测系统物理内存,并按比例分配内部内存池。如果宿主机上还有大量进程在抢内存,虚拟机的实际可用内存就会大打折扣。遇到这种场景,先把宿主机的浏览器、IDE、虚拟机软件之外的大型应用全部关掉,再尝试安装。

如果安装过程中确实因为内存问题中断了,不要马上重新运行安装脚本,先扩展 Swap 空间作为缓冲:

# 创建 32GB swap 文件 dd if=/dev/zero of=/swapfile bs=1M count=32768 chmod 600 /swapfile mkswap /swapfile swapon /swapfile

然后编辑 /etc/fstab,把/swapfile none swap sw 0 0加进去,确保重启后依然生效。Swap 不能解决 HANA 对内存的硬性需求,但能在系统层面减少 OOM 风险,给排查留出时间。

5.2 连不上库的排查路径

客户端连不上 HANA,排查顺序很重要,我建议从下往上查:先确认数据库进程存活,再查端口监听,最后检查防火墙。很多新手一上来就怀疑密码不对,其实多数情况根本到不了认证这一步。

第一步,在虚拟机里执行HDB info,确认进程都在。如果 nsserver 都没起来,说明数据库挂了,后面的一切都没意义。第二步,监听端口检查:

ss -tlnp | grep 3901

如果输出里没有 39013 的监听记录,说明 HANA 实例的端口配置有异常,用HDB start尝试重启数据库。第三步,在宿主机上 nc 测试端口连通性,如果端口不通,基本可以确定是防火墙拦截。

另外有一个非常容易被忽略的点:客户端 JDBC URL 里填的数据库名要区分大小写。HANA 的租户库名是严格区分大小写的,你在连接参数里写 SYSTEMDB 还是 systemDB,效果完全不同。DBeaver 这类 GUI 工具会自动处理,但如果用代码连,这个坑会非常隐蔽。

5.3 密码遗忘与日志增长的应急处理

HANA SYSTEM 用户的密码忘记了,不用慌,可以借用操作系统级认证来找回。以 hxeadm 用户登录虚拟机,先查看 userstore 里已有的连接密钥:

hdbuserstore LIST

安装 HANA 时系统会自动生成一个 SYSTEM 密钥,有了这个密钥,就可以免密登录 SYSTEM 用户,然后重置密码:

hdbsql -U SYSTEM "ALTER USER SYSTEM PASSWORD \"NewPassword1234\""

如果你连 hdbuserstore 里的密钥都删了,那只能走 SAP 支持通道处理,在 console 模式下启动 HANA 来做密码恢复。整套流程比较麻烦,所以日常使用中建议尽量不要手动删除 HANA 生成的默认密钥。

还有一个日常运维关注点是日志增长。HANA 默认的日志模式是 append,时间长了日志文件会越来越大。学习环境的数据量小,但日志膨胀的速度依然不可忽视。一个实用的小技巧是把日志模式切换为 overwrite:

ALTER SYSTEM ALTER CONFIGURATION ('global.ini', 'SYSTEM') SET ('persistence', 'log_mode') = 'overwrite' WITH RECONFIGURE;

这条命令可以避免日志无限制增长,对于学习环境来说非常实用。切换后旧日志会被自动清理,磁盘压力会小很多。

写在最后的一点个人体会

搭过的环境多了以后,我发现 HANA 这套东西其实并没有想象中那么难伺候。它最挑剔的就是内存和主机名解析,只要这两点处理好了,后面的安装和连接都非常顺。反复装了几轮之后,我自己总结了一套心法:每次搭环境之前先整理出一张检查表,把内存、磁盘、hosts、防火墙这些固定项列出来,确认没问题再动手,省心得多。

如果这篇文章里的东西你都跑通了,我建议你顺势做三件事:一是把示例数据导入表里,练一练 HANA 的列式存储查询优化;二是了解一下 XSA 的 xs 命令,体验一下如何在 HANA 里跑一个简单的 Node.js 应用;三是从 Python 连数据库的角度,用 hdbcli 写一个小脚本,为以后做数据分析和自动化运维提前打个底。学习数据库这件事,把环境稳定跑起来,就等于成功了一大半,剩下的就是靠时间和练习慢慢堆积了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 8:58:30

工业设备接入平台十年演进:协议、监控、日志与诊断的实践之路

1. 十年前,我们是怎么被协议碎片化逼疯的2013年前后,我接手了公司第一个设备接入平台项目。当时摆在我们面前的现实是:现场有二十多种设备,PLC、传感器、数控机床、冷库控制器、能耗采集器,每一种都有自己的通信方式。…

作者头像 李华
网站建设 2026/10/7 8:57:33

AI数字人直播怎么做?从选型到推流全流程实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 8:57:22

ESP32云端开发新姿势:ESP-Mosaico与烧录工具v3.6.5实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 8:56:34

小程序上门维修系统源码精讲:从环境搭建到三端联调

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 8:56:34

YOLO球类检测实战:篮球排球网球数据集训练与优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华