云和恩墨技术专家

现就职于云和恩墨,为某省电信公司数据库运维服务;在IT行业拥有10年以上的工作经历。擅长 ORACLE 数据库运维管理、shell 脚本开发;长期服务于电信、金融,政府行业;具有丰富的数据库经验。

本文整理自上周四晚云和恩墨大讲堂分享的关于主题:Oracle 12c新特性-多租户的维护管理。

概述

Oracle 12cRelease 1自从2013年发布以来已经有3年多时间了,新的Release版本Oracle 12c R2的发布时间也在翘首以盼。在已发布的12c中有增加了很多新特性,包括多租户、存储优化(heat map,ADO)、内存组件(In-Memory)等等。目前已经有用户开始尝鲜使用12c中的新功能,今天和大家介绍和分享12c中多租户的特点及多租户的维护管理方法。

1多租户的结构和相关的概念

简单来说,12c中的多租户架构是一个容器数据库(multitenant Container DataBase ,CDB)中包含多个可插拔数据库(PluggableDataBases)。在传统的数据库架构中Oracle实例与数据库的关系是1对1(单实例环境)和1对N(RAC数据库),而在多租户的环境下,实例与数据库的关系为N对1(单实例CDB环境)和N对N(RAC多租户CDB环境)。

下面是多租户的逻辑和物理结构:

从逻辑结构来看,以上图为例,一个CDB中包含有一个根容器(CDB$ROOT),一个种子容器(PDB$SEED),两个PDB分别是hrpdb和salepdb。

根容器(root container ,CDB$ROOT):CDB ROOT中主要保存一些元数据和公共对象。在容器数据库中,PDB有自己独立的SYSTEM和SYSAUX表空间保存自己数据库中的元数据信息。

种子容器(seed pdb,PDB$SEED):是系统提供用来创建PDB的模板。无法在seed容器中添加或修改对象。在CDB启动之后,SEED PDB的状态是READ ONLY的状态。

PDB(Pluggabledatabases):一个CDB中可以包含0~N个PDB,PDB是提供应用服务的数据库,在上图中包含salespdb和hrpdb两个PDB,正常情况下是由salespdb和hrpdb对外提供服务,CDB$ROOT只是用来对数据库进行管理,与Unix/Linux系统中的root用户类似。新建的CDB中不包含PDB,需要单独去创建。

从物理结构来看,在一个CDB容器中,包含有:

  • 共用的控制文件;

  • 共用的redo日志文件;

  • 一个或多个临时表空间(默认情况下,CDB和PDB共用CDB$ROOT中的临时表空间,但PDB也可以创建自己的临时表空间);

  • 共用一个UNDO表空间;

  • 各自独立的SYSTEM和SYSAUX表空间(即每个PDB会有各自SYSTEM和SYSAUX表空间);

  • PDB各自应用表空间数据文件。

2创建和删除PDB

PDB的创建有下面几种方法:

  • 从PDB$SEED中创建PDB;

  • 通过克隆一个现有的PDB数据库或非CDB数据库(non-CDB)来创建一个新的PDB;

  • 使用XML元数据描述文件将数据库插入到CDB中;

  • 使用DBMS_PDB方式;

a.通过seed新建一个PDB数据库

创建一个名字为salespdb的PDB,其应用用户默认表空间为sales,数据文件保存路径在/disk1/oracle/dbs/salespdb。创建的SQL语句如下:

CREATE PLUGGABLE DATABASE salespdb ADMIN USERsalesadm IDENTIFIED BY password

STORAGE(MAXSIZE 2G MAX_SHARED_TEMP_SIZE 100M)

DEFAULT TABLESPACEsales

DATAFILE'/disk1/oracle/dbs/salespdb/sales01.dbf' SIZE 250M AUTOEXTEND ON

PATH_PREFIX= '/disk1/oracle/dbs/salespdb/'

FILE_NAME_CONVERT = ('/disk1/oracle/dbs/pdbseed/','/disk1/oracle/dbs/salespdb/');

在上面的创建语句中,通过STORAGE子句中的MAXSIZE和MAX_SHARED_TEMP_SIZE来限制PDB可以分配空间大小和从CDB中分配的临时表空间大小。我们可以指定大小,也可以设置为UNLIMITED.

通过PATH_PREFIX和FILE_NAME_CONVERT子句来指定数据文件的名称。

也可以通过下面的命令来创建:

CREATE PLUGGABLE DATABASE salespdb ADMIN USERsalesadm IDENTIFIED BY password FILE_NAME_CONVERT = ('/disk1/oracle/dbs/pdbseed/','/disk1/oracle/dbs/salespdb/');

b.通过克隆一个现有的PDB数据库或非CDB数据库(non-CDB)来创建一个新的PDB

通过现有的pdb1创建新的PDB pdb2:

CREATE PLUGGABLE DATABASE pdb2 FROM pdb1

FILE_NAME_CONVERT = ('/disk1/oracle/pdb1/', '/disk2/oracle/pdb2/');

通过non-cdb创建pdb

CREATE PLUGGABLE DATABASE pdb2 FROM pdb1

(1)首先需要将non-cdb置为只读

(2)创建连接指向non-cdb的dblink

(3)创建pdb

CREATEPLUGGABLE DATABASE pdb2 FROM mydb@mydb_link FILE_NAME_CONVERT =('/disk1/oracle/non-cdb1/', '/disk2/oracle/pdb2/‘);

CREATEPLUGGABLE DATABASE pdb2 FROM NON$CDB@mydb_link FILE_NAME_CONVERT =('/disk1/oracle/non-cdb1/', '/disk2/oracle/pdb2/‘);

上面这两个语句是等效的。

(4)在pdb上运行@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql脚本

c.使用XML元数据描述文件将数据库插入到CDB中

这个创建PDB的方式其实等于是使用XML描述文件对PDB做迁移。即使用XML描述文件的方式将PDB从一个CDB迁移到另一个CDB中。在网络不通的情况下可以使用,如果网络能正常连接的情况下,可以参考使用dblink进行迁移。

具体的创建过程如下:

首先生成XML描述文件

exec dbms_pdb.DESCRIBE('/home/oracle/pdbenmo3_describe.xml','PDBENMO3');

使用keepdatafile的方式drop掉 PDB

drop pluggable database PDBENMO3 keep datafiles;

在数据库中验证XML描述文件是否可以插入到目标的CDB环境中

DECLARE

compatible CONSTANT VARCHAR2(3) :=

CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

pdb_descr_file => '/home/oracle/pdbenmo3_describe.xml',

pdb_name      => 'PDBENMO3')

WHEN TRUE THEN 'YES'

ELSE 'NO'

END;

BEGIN

DBMS_OUTPUT.PUT_LINE(compatible);

END;

将PDBPROD3中的数据文件目录改名mv为PDBTEST01(数据文件中存在PDBENMO3也改为PDBTEST01);

将数据库改名插入到CDB中,使用NOCOPY的方式:

CREATE PLUGGABLE DATABASE PDBTEST01 USING'/home/oracle/pdbenmo3_describe.xml'

SOURCE_FILE_NAME_CONVERT= ('PDBENMO3', 'PDBTEST01')

NOCOPY;

d.使用DBMS_PDB方式

通常来说,我们将Non-CDB数据库迁移到PDB有下面几种情况和方法:

(1)通过克隆的方式进行迁移,即第二种方式中使用dblink方式进行创建,这种方式需要PDB和Non-CDB数据库的版本都要高于12.1.0.2,如果没有12.1.0.2,则需要将数据库升级到12.1.0.2之后的版本

(2)通过DBMS_PDB的方式生成XML元数据文件进行迁移。这种方式要求Non-CDB数据库的版本高于12c。该节我们主要介绍这种方法

(3)使用数据泵EXPDP/IMPDP的方式。这种方式要求Non-CDB数据库的版本高于11.2.0.3,在使用该方式的时候,expdp数据时,需要添加VERSION参数version=12。如果Non-CDB数据库版本低于11.2.0.3,则可以使用传输表空间的方式进行迁移

(4)使用GoldenGate或类似于Goldengate的工具进行迁移

我们看一下使用DBMS_PDB的方式将Non-CDB转化为PDB对方式,步骤如下:

(1)将Non-CDB数据库置为只读

(2)生成XML描述文件

exec dbms_pdb.describe('/home/oracle/prod4_describe.xml');

(3)关闭Non-CDB数据库

(4)在CDB数据库中使用XML描述文件创建PDB。

CREATE PLUGGABLE DATABASE ncdb USING'/home/oracle/prod4_describe.xml' COPY FILE_NAME_CONVERT =('/u01/app/oracle/oradata/PROD4','/u01/app/oracle/oradata/PRODCDB/ncdb');

创建完成之后不要立即打开PDB,还需要执行noncdb_to_pdb.sql脚本

(5)执行noncdb_to_pdb.sql脚本

alter session set container=NCDB;

--NCDB为新建的PDB名称

@?/rdbms/admin/noncdb_to_pdb.sql

(6) 确认没有报错后,打开数据库

alter pluggable database NCDB open;

对于PDB的删除,有两种情况:保留数据文件和不保留数据文件

对于不保留数据文件的情况,直接使用drop pluggable database including datafiles即可

drop pluggable database pdb_name includingdatafiles;

对于需要保留数据文件的情况,则在删除前需要生成描述文件将数据库unplug,然后再进行删除:

alter pluggable database PDBENMO2 unplug into'/home/oracle/pdbenmo2_describe.xml';

drop pluggable database PDBENMO2 keep datafiles;

以上是对多租户数据库的创建和删除的维护操作,接下来我们分享一下CDB和PDB的启动停止维护内容

3多租户数据库的管理

CDB的启动和停止

CDB实例的启动和停止与传统的Non-CDB数据库启动一样,同样经历nomount,mount,open几个阶段,在各个阶段中读取的数据库文件也相同。默认情况下,当CDB启动之后,CDB$ROOT是自动打开的,而CDB$SEED无法打开,其状态为READ ONLY状态。其余PDB的状态默认情况下也都是MOUNT,如果需要设置PDB随CDB启动而打开,简单设置一下即可。

在12.1.0.1版本中,如果需要PDB随CDB启动而打开,需要通过创建触发器来实现。

CREATEOR REPLACE TRIGGER open_pdbs

AFTER STARTUP ON DATABASE

BEGIN

EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALLOPEN';

END open_pdbs;

/

在12.1.0.2版本中,可以保存PDB的状态,当下次CDB重启的时候,会将PDB启动到保存的状态下。因此我们可以将PDB的状态保存为open,当下次CDB启动之后,直接打开PDB。

其实现方法如下

alter pluggable database pdbenmo3 save state;

保存的状态通过dba_pdb_saved_states视图查看

删除保存的状态:

alter pluggable database pdbenmo3 discard state;

PDB的打开和关闭

打开PDB时,需要以SYSOPER或SYSDBA身份连接到CDB$ROOT,然后发出ALTERPLUGGABLE DATABASE OPEN语句,可以指定一个或多个PDB来打开。

alter pluggable database pdbenmo3 open;

alter pluggable database all open;

alter pluggable database all except pdbenmo3 open;

使用show pdb 或查询v$pdbs视图查看打开状态

也可以使用sysdba身份连接到PDB中打开PDB。这种情况下,不必命名要打开的PDB。

启动和关闭PDB:


关闭PDB时,以SYSOPER或SYSDBA身份连接到CDB$ROOT,然后发出alterpluggable database close,制定一个或多个PDB名称进行关闭


表空间管理

在多租户数据库环境中,对数据库表空间的管理与传统的非多租户数据库管理基本相同。无论是对用户表空间还是临时表空间,唯一需要注意的是,在对表空间数据文件进行维护的时候,需要确认对象是属于哪个PDB或者是属于CDB$ROOT。

查看当前PDB的方法:

SQL> show pdbs

CON_IDCON_NAME              OPEN MODE RESTRICTED

---------- ---------------------------------------- ----------

2 PDB$SEED               READ ONLY NO

3 PDBENMO1               MOUNTED

4 PDBENMO2               READ WRITE NO

SQL> show pdbs

CON_IDCON_NAME              OPEN MODE RESTRICTED

---------- ---------------------------------------- ----------

2 PDB$SEED               READ ONLY NO

3 PDBENMO1               MOUNTED

4 PDBENMO2               READ WRITE NO

或者查看dba_pdbs视图

切换PDB

alter session set container=pdb_name; —切换到某个PDB

alter session set container=cdb$root; —切换到cdb root

或者可以使用sqlplus或conn的方式直接连到相应的pdb数据库中

用户管理

相比Oracle 11g之前版本中的用户管理,多租户数据库中数据库的管理有两种:本地用户和公共用户。本地用户即为某个PDB中的数据库用户,是仅存在某个PDB中的数据库用户,其管理方法与传统的非CDB环境相同。相比本地用户,公共用户是在多个PDB中具有相同用户名和验证身份的用户。

公共用户的名称不能与所有PDB中任何本地用户名称相同。公共用户是在根和每个现有和将来的PDB中具有相同身份的数据库用户。

本地用户的用户信息保存在属主PDB中的SYSTEM表空间中,而公共用户的用户信息在CDB$ROOT和各个PDB中的SYSTEM表空间中都有保存。

公共用户创建需要在CDB$ROOT根容器下创建:

SQL> alter session set container=cdb$root;

Session altered.

common_user_prefix参数设定要求公共参数需要用C##开头,可以调整修改

SQL> show parameter common_user_prefix

NAME                     TYPE VALUE

------------------------------------ -----------------------------------------

common_user_prefix             string    C##

创建公共用户

SQL> create user C##user1 identified by oracle

User created.

查看公共用户,分别在CDB$ROOT和各个PDB中存在:

SQL> select username,con_id from cdb_users whereusername like '%USER1%';

USERNAME        CON_ID

---------------- ----------

C##USER1          1

C##USER1          3

C##USER1          4

管理角色和权限

与公共用户和本地用户类似,在创建角色role的时候,也会有公共角色和本地角色的区别,当在根容器中创建角色时,该角色为公共角色,而在具体某一个PDB中创建角色时,该角色为本地角色。

公共角色可以授予公共用户,也可以授予本地用户。同样,在某一个PDB中,可以给一个公共用户授予公共角色,也可以给它赋予本地角色。所以,公共用户在不同的PDB中的权限可能是不同的。

可以在根容器CDB$ROOT下给所有的公共用户授予公共权限,如果需要赋予一个公共权限,则在赋权SQL命令后面需要加上container=all子句。如下:

--创建公共角色role

SQL> create role c##role1;

Role created.

--当前公共用户C##USER1没有被赋予任何角色权限

SQL> select grantee,granted_role,con_id from cdb_role_privs where grantee like '%C##USER1%';

no rows selected

--给公共用户赋予公共角色role1

SQL> grant c##role1 to c##user1 container=all;

Grant succeeded.

--赋权成功

SQL> select grantee,granted_role,con_id from cdb_role_privs where grantee like '%C##USER1%';

GRANTEE       GRANTED_ROLE  CON_ID

------------------------------ ------------------------------ ----------

C##USER1       C##ROLE1       3

C##USER1       C##ROLE1       4

C##USER1       C##ROLE1       1

同样对于公共权限也一样

--当前公共用户C##USER1没有给赋予任何系统权限

SQL> select grantee,privilege,con_id from cdb_sys_privs where grantee like '%C##USER1%';

no rows selected

--用户C##USER1赋予create session权限但不加container=all子句

SQL> grant create session to C##USER1;

Grant succeeded.

--使用container=all子句给用户C##USER1赋予create table权限

SQL> grant create table to C##USER1 container=all;

Grant succeeded.

--查看用户的权限,可以看到如果使用container=all子句,则授予的是公共权限。否则是本地权限

SQL> select grantee,privilege,con_id from cdb_sys_privs where grantee like '%C##USER1%';

GRANTEE       PRIVILEGE    CON_ID

------------------------------ ---------------------------------------- ----------

C##USER1       CREATE SESSION 1

C##USER1       CREATE TABLE 1

C##USER1       CREATE TABLE 3

C##USER1       CREATE TABLE 4

在CDB多租户环境中各PDB的资源分配

对于在多租户数据库的维护中,有时候考虑到多个PDB之间可能会存在CPU,内存等资源的竞争,如何去规划和限制这些PDB的资源分配,以避免PDB之间相互影响。

在传统以前的数据库中,Oracle一直提供了资源管理器resource manager工具对各个schema之间的资源进行分配和限制。在Oracle 12c的多租户环境中,我们同样可以使用resource manager对多租户中各个PDB的资源进行规划和分配。

下面是一个规划的示例:

为CDB数据库PRODCDB中的PDBENMO1,PDBENMO2,PDBENMO3配置资源管理器,

PDBENMO1 得到5 份共享CDB 资源

PDBENMO2 得到3 份共享CDB 资源

PDBENMO3 得到2 份共享CDB 资源

没有PDB 可以得到多于80%的可用cpu 时间

没有PDB 可以得到多于30%的parallel_servers_target

DECLARE

spfileValue VARCHAR2(1000);

execText VARCHAR2(1000);

scopeValue VARCHAR2(30) := 'MEMORY';

planName VARCHAR2(100) :='DAYTIMEP';

BEGIN

dbms_resource_manager.clear_pending_area();

dbms_resource_manager.create_pending_area();

dbms_resource_manager.create_cdb_plan( plan => 'PLAN_P', comment => '');

dbms_resource_manager.create_cdb_plan_directive(

plan => 'PLAN_P',

pluggable_database => 'PDBENMO1',

comment => '',

shares => 5,

utilization_limit => 80,

parallel_server_limit => 30 );

dbms_resource_manager.create_cdb_plan_directive(

plan => 'PLAN_P',

pluggable_database => 'PDBENMO2',

comment => '',

shares => 4,

utilization_limit => 80,

parallel_server_limit => 30 );

dbms_resource_manager.create_cdb_plan_directive(

plan => 'PLAN_P',

pluggable_database => 'PDBENMO3',

comment => '',

shares => 1,

utilization_limit => 80,

parallel_server_limit => 30 );

dbms_resource_manager.submit_pending_area();

END;

/

如上,可以使用dbms_resource_manager资源管理器包对CDB中各个PDB分配的资源进行规划和限制。

4总结

  1. 部署的数据库对硬件的资源消耗并不大,系统压力比较小

  2. 具有实例和存储空间的开销,因此同一台服务器上不能同时部署很多套数据库,不同的应用分散在不同的服务器上

  3. 每一套数据库的维护不是很复杂,但是维护的数据库量比较大

  4. 不需要大量的时间来对数据库进行升级或打补丁

对于以上这种情况,我们可以考虑使用Oracle 12c多租户的功能,将很多个数据库集中到CDB中进行维护管理。

多租户数据库的优点:

(1)在集中管理的平台中操作多个数据库,其成本更低:

—实例开销较低

—存储成本较低

(2)减少DBA的重复维护工作量并保证维护的安全性

—对应用来说,数据库的连接并没有改变,不会涉及应用程序的更改

—对DBA数据库管理员来说,减少了数据库的维护量

—数据库维护更方便,CDB/PDB的维护工作与传统的维护方式没有太大改变,相比在升级和打补丁方面更方便

—新建PDB和迁移比较快速

(3)不同的PDB之间相互隔离,不会相互干扰影响

往期大讲堂精彩主题回顾

  • 20160107期:李真旭 - 动手为王 - 整合迁移与数据恢复实践

  • 20160113期:敬勇 - 一条执行时间小于1秒的 SQL 引发的性能问题

  • 20160114期:郑保卫 - 索引优化策略及实战

  • 20160310期:李华 - 故障分析 | library cache latch 竞争案例分享

  • 20160317期:于远 - 一条让人欲罢不能的 SQL给我的启发

  • 20160324期:皇甫晓飞 - 合理使用存储过程提高运维效率

  • 20160331期:戴明明 - 基于PCIE 闪存卡的 Oracle 数据库使用(一)

  • 20160331期:戴明明 - 基于PCIE 闪存卡的 Oracle 数据库使用(二)

  • 20160407期:怀晓明 - 细致入微 | 让 SQL 优化再多飞一会儿

  • 20160414期:李建国 - 从容灾迈向双活案例分享

  • 20160421期:盖国强 - Oracle 数据库的架构演进和我的学习之路

  • 20160428期:黄嵩 - 一次 truncate 核心表衍生的信息系统安全思考

  • 20160505期:陈龙 - 探究 Oracle 高水位对数据库性能影响

  • 20160519期:李轶楠 - 意料之外的 RAC 宕机罪犯 - 子游标

  • 20160526期:程昌明 - 通过 Oracle 日志文件了解 CRS 的启动过程

  • 20160602期:李真旭 - 数套 ASM RAC 的恢复案例

  • 20160616期:李翔宇 - 轻轻揭开 b*tree 索引结构的神秘面纱

  • 20160623期:黄宸宁 - 一次特殊的 ORA-04030 故障处理

  • 20160630期:钟时荣 - SQL性能突然降低引起的业务办理缓慢案例一则

  • 20160707期:易欣 - TX - row lock contention 的一些场景

  • 20160714期:巩飞 - Oracle 实用技巧之不知道密码情况下 dblink 的迁移

  • 20160721期:李磊 - 深入剖析 ORA-04031 的前世今生

  • 20160728期:杨俊 - 炎炎夏日-恩墨小王子带你玩转“数据卫士”Data Guard

  • 20160804期:彭文元 - 中间件 BES 连接池的配置和问题诊断方法

  • 20160811期:尹涛- 由 DRM 引起的 ORA-00481错误

Oracle 12c新特性-多租户的维护管理相关推荐

  1. 【云和恩墨大讲堂】高凯 | Oracle 12c 新特性-多租户的维护管理

    "云和恩墨大讲堂" 线上课程周四晚继续开讲.本期我们邀请的嘉宾是云和恩墨西北区技术专家 - 高凯,在这里跟大家分享一下 Oracle 12c 新特性方面的主题.课程以图文形式在微信 ...

  2. Oracle 12c新特性--LREG进程专门负责注册实例服务

    Oracle 12c引入了一些大量的新特性,数据库隐藏参数12.2比11.2就多了2000多个, 同时对之前版本的结构也发生了一些变化,虽然不如有些特性像temporary undo\immemory ...

  3. Oracle 12C 新特性之扩展数据类型(extended data type)

    Oracle 12C 新特性-扩展数据类型,在12c中,与早期版本相比,诸如VARCHAR2, NAVARCHAR2以及 RAW这些数据类型的大小会从4K以及2K字节扩展至32K字节.只要可能,扩展字 ...

  4. oracle 12c undo,Oracle 12c 新特性之临时Undo--temp_undo_enabled

    Oracle 12c 新特性之临时Undo--temp_undo_enabled 每个 Oracle 数据库包含一组与系统相关的表空间,例如 SYSTEM , SYSAUX , UNDO&TE ...

  5. oracle12c 新增维护时间窗口,ORACLE 12C新特性-自动维护全局索引 | 信春哥,系统稳,闭眼上线不回滚!...

    今天在网上看了一篇关于12C新特性-自动维护全局索引的帖子,经测试,貌似根本不是那么回事呀.如果对分区表进行分区DDL操作,如果不加update index字句,全局索引就会失效,下面先看一下是11. ...

  6. oracle12c asmfd,Oracle 12c新特性--ASMFD(ASM Filter Driver)特性

    1 说明 ASMFD 是 12.1 中就引入的新特性,它可以不用手动配置 ASM 磁盘,更重要的是它可以保护磁盘被其他非 Oracle 操作复写,例如 dd , echo 等命令. 更为详尽的介绍,请 ...

  7. oracle中pdb,Oracle 12C新特性-CDB和PDB 详解

    最近看到好多人都在尝试Oracle中的12C新特性-容器数据库,今年3月Orcle推出了Release2版本,可以算是一个稳定版本了.下午着手尝试了一下,还是蛮不错得 1.前言 CDB与PDB是Ora ...

  8. oracle desc能看约束,ORACLE 12C新特性-DESC显示不可见字段 | 信春哥,系统稳,闭眼上线不回滚!...

    之前写过一篇关于12C新特性-不可见字段的文章,详见http://www.dbdream.com.cn/2014/01/19/oracle-12c%E6%96%B0%E7%89%B9%E6%80%A7 ...

  9. Oracle 12c 新特性

    Oracle数据库12c的一些新特性总结,包括数据库管理.RMAN.高可用性以及性能调优等内容. 主要内容: 在线迁移活跃的数据文件 表分区或子分区的在线迁移 不可见字段 相同字段上的多重索引 DDL ...

最新文章

  1. Hadoop系列四:Hadoop之Hive篇
  2. python实验过程心得体会_20192416 实验四《Python程序设计》综合实践报告
  3. VC/MFC Combo Box控件的用法
  4. linux salt生成,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  5. 3 地理位置定位_IP地理定位API的十大用途和应用
  6. Python学习之路20-数据模型
  7. python可以做特效吗_学习mel语言,Python,JavaScript到什么程度才能做一下大型特效,要自已开发插件脚本呢?...
  8. mysql mysqldumpslow_慢日志分析工具—mysqldumpslow 和 mysqlsla
  9. 空间自相关的知识总结
  10. 使用FragmentTabHost出现的错误!
  11. linux 线程_Linux线程编程专题之线程和线程函数介绍
  12. CoffeeScript学习(3)—— 函数
  13. javweb音乐网站_音乐网站javaweb源码
  14. MEM/MBA 写作-论证有效性分析(09)逻辑缺陷-误用百分数滑坡谬误
  15. PI3体验之无线网AP模式设定及热点分享
  16. POI生成word文档,图片显示为空白或不显示
  17. 新能源光伏发电的原理是怎样太阳能光伏阵列并网发电仿真模拟运行演示系统
  18. 下拉多选checkbox
  19. 顺义区服务器虚拟化,北京银行顺义数据中心私有云项目
  20. 后端接口返回一张图片

热门文章

  1. 我的滑板鞋-2017年在魅力之都继续摩擦
  2. 无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。
  3. win7记事本的小窍门应用可以学会
  4. 记事本字符编码没有Unicode选项
  5. 【Android开发】计算机网络基础知识点,如何完成网络请求过程?
  6. 电路及esd静电防护
  7. 书论51 朱文长《续书断》
  8. 怎么从pdf中提取图片
  9. idea项目打包和部署
  10. 【NE】北邮循序渐进学习NE