{"id":297,"date":"2018-08-06T16:36:05","date_gmt":"2018-08-06T14:36:05","guid":{"rendered":"https:\/\/blog.kurschies.de\/?p=297"},"modified":"2018-11-23T10:33:46","modified_gmt":"2018-11-23T09:33:46","slug":"fast-provisioning-with-snapshot-clones","status":"publish","type":"post","link":"https:\/\/blog.kurschies.de\/index.php\/2018\/08\/06\/fast-provisioning-with-snapshot-clones\/","title":{"rendered":"fast provisioning with snapshot clones"},"content":{"rendered":"<p>Every DBA know&#8217;s the situations, where your boss \/ customer ask you to copy fresh data into the test database&#8230; since this blog is about oracle databases, we are solving this issue usually either with &#8220;datapump&#8221; or &#8220;rman duplicate&#8221; &#8211; and there is nothing wrong about it. But now imagine, we are talking about more than 400 test environments. To satisfy all testers, the production is exported every day (although not all test databases are refreshed daily), which takes several hours every day. And then there are a lot of costs for the expensive SAN storage&#8230; So i was asked if there is a better, faster and cheaper solution. As you may suppose, after some research I found the 12c new feature of doing snapshot clones&#8230; and it&#8217;s really nice, so I want to show you how it works.<br \/>\n<br \/>\nAdvantages<\/p>\n<ul>\n<li>really fast provisioning (a few seconds)<\/li>\n<li>very efficient storage usage<\/li>\n<\/ul>\n<p>Disadvantages<\/p>\n<ul>\n<li>it&#8217;s based on pluggable database, so you need the multitenant option license<\/li>\n<li>only 3 storage types\/vendors are certified until now: ZFS, ACFS and NetApp<\/li>\n<\/ul>\n<p>since i do not have a netapp or zfs applicance, I&#8217;m using ACFS for my test, but there are also some things to consider:<\/p>\n<ul>\n<li>it&#8217;s slower than ASM<\/li>\n<li>you have to install a RAC &#8211; oracle restart is not sufficient&#8230; nevertheless it&#8217;s OK to run a 1 node &#8220;cluster&#8221; where you don&#8217;t want to buy the RAC option.<\/li>\n<\/ul>\n<p>OK, lets start&#8230; first &#8211; as mentioned above &#8211; we need a rac. If you don&#8217;t know how to install, i recommend to visit this site: <a href=\"https:\/\/en.wikibooks.org\/wiki\/RAC_Attack_-_Oracle_Cluster_Database_at_Home\" rel=\"noopener\" target=\"_blank\">rack attack<\/a>.<br \/>\nNext we are going to create an ACFS volume&#8230; this can be done easily with asmcmd:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbash&gt; asmcmd volcreate -G &lt;diskgroup&gt; -s 10G &lt;volume_name&gt;\r\n<\/pre>\n<p>of course you have to replace the variables in the brackets&#8230; in my test environment I created a dedicated diskgroup called ACFS and created a volume named oradata.<br \/>\nthen we have to check, which device name was reserved for this new volume<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbash&gt; asmcmd volinfo -G ACFS oradata\r\nDiskgroup Name: ACFS\r\n\r\n         Volume Name: ORADATA\r\n         Volume Device: \/dev\/asm\/oradata-30\r\n         State: ENABLED\r\n     ... \r\n<\/pre>\n<p>Great! now we have to crate a filesystem on that virtual block device<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nmkfs.acfs \/dev\/asm\/oradata-30\r\n<\/pre>\n<p>and last step: mount the volume<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nsudo \/sbin\/acfsutil registry -a \/dev\/asm\/oradata-30 \/u00\/app\/oracle\/oradata\r\n<\/pre>\n<p>that&#8217;s it &#8211; now the clusterware should detect the new entry in the OCR (the check is running every 30 seconds) and automount the volume&#8230; if not, you can do it manually:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nsudo mkdir \/u00\/app\/oracle\/oradata\r\nsudo \/bin\/mount -t acfs \/dev\/asm\/oradata-30 \/u00\/app\/oracle\/oradata\r\n<\/pre>\n<p>next chapter: create the database. Since i want to simulate the complete way, I created two databases: one is the source (=production) called ORCL, the other the target (=test) database named CDB. Both databases are located on ASM disksgroups (not the ACFS volume!). The source is installed the classical way (no multi- or singletenant) while the target is installed as CDB but without any PDB.<br \/>\nTo use the PDB-clone-feature, we have to create a database link from the target to the source first:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nSYS@CDB1&gt;CREATE DATABASE LINK orcl CONNECT TO system IDENTIFIED BY &lt;password&gt; USING 'rac01-scan:1521\/orcl';\r\n<\/pre>\n<p>I just used the user &#8220;system&#8221;, but any other user with the &#8220;create session&#8221; and &#8220;create pluggable database&#8221; privilege is sufficient.<br \/>\nnext we have to prepare the directory and create the master pdb<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbash&gt; mkdir -p \/u00\/app\/oracle\/oradata\/CDB\/prod_seed\r\nsql&gt;  CREATE PLUGGABLE DATABASE prod_seed FROM NON$CDB@orcl CREATE_FILE_DEST='\/u00\/app\/oracle\/oradata\/CDB\/prod_seed';\r\n<\/pre>\n<p>based on the size of the database and the speed of your storage, this will take some minutes&#8230;<br \/>\nwhen finished, you have a seed pdb with the interal structure of a non-cdb&#8230; so you have to convert it first.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nSQL&gt; ALTER SESSION SET CONTAINER=prod_seed;\r\nSQL&gt; @$ORACLE_HOME\/rdbms\/admin\/noncdb_to_pdb.sql\r\nSQL&gt; ALTER PLUGGABLE DATABASE prod_seed OPEN;\r\nSQL&gt; ALTER PLUGGABLE DATABASE prod_seed OPEN READ ONLY FORCE;\r\nSQL&gt; ALTER PLUGGABLE DATABASE prod_seed SAVE STATE;\r\n<\/pre>\n<p>please note that you have to open the database first to make some kind of instance recovery, afterwards you can bring the pdb in the correct state to be a seed database.<br \/>\nAnd now: create the clone<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbash&gt; mkdir -p \/u00\/app\/oracle\/oradata\/CDB\/clone1\r\nSQL&gt; CREATE PLUGGABLE DATABASE clone1 FROM prod_seed CREATE_FILE_DEST='\/u00\/app\/oracle\/oradata\/CDB\/clone1' SNAPSHOT COPY;\r\nSQL&gt; ALTER PLUGGABLE DATABASE clone1 OPEN;\r\n<\/pre>\n<p>P.S. in some guidelines you will be advised to set the parameter clonedb to true &#8211; don&#8217;t do, at least if you are using ACFS! it&#8217;s only necessary if your storage can&#8217;t do snapshots, so oracle is trying to do some magic, don&#8217;t know if its working. For further details, just read the <a href=\"https:\/\/docs.oracle.com\/database\/121\/SQLRF\/statements_6010.htm\" rel=\"noopener\" target=\"_blank\">manual<\/a> (search for &#8220;SNAPSHOT COPY&#8221;)<br \/>\nOK, and now? Finished! &#8230; and where is the magic? the last &#8216;create pluggable database&#8230;&#8217; just took a few seconds, regardless the size of the seed database, and it consumes no space at all (at least at the moment)&#8230;<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbash&gt; du -sh *\r\n228K    clone1\r\n3.6G    prod_seed\r\n<\/pre>\n<p>and what&#8217;s inside?<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nls -lhr clone1\/CDB\/72C5EDFE41727F36E0531F01100AB18B\/datafile\/\r\ntotal 20K\r\nlrwxrwxrwx. 1 oracle dba 154 Aug  6 16:17 o1_mf_users_fpjp2wdt_.dbf -&gt; \/u00\/app\/oracle\/oradata\/.ACFS\/snaps\/72C5EDFE41727F36E0531F01100AB18B\/CDB\/prod_seed\/CDB\/72C340E0CEE355E1E0531F01100AFEB9\/datafile\/o1_mf_users_fpjbvo7t_.dbf\r\nlrwxrwxrwx. 1 oracle dba 157 Aug  6 16:17 o1_mf_undotbs2_fpjp2wdg_.dbf -&gt; \/u00\/app\/oracle\/oradata\/.ACFS\/snaps\/72C5EDFE41727F36E0531F01100AB18B\/CDB\/prod_seed\/CDB\/72C340E0CEE355E1E0531F01100AFEB9\/datafile\/o1_mf_undotbs2_fpjbvo7g_.dbf\r\nlrwxrwxrwx. 1 oracle dba 157 Aug  6 16:17 o1_mf_undotbs1_fpjp2wco_.dbf -&gt; \/u00\/app\/oracle\/oradata\/.ACFS\/snaps\/72C5EDFE41727F36E0531F01100AB18B\/CDB\/prod_seed\/CDB\/72C340E0CEE355E1E0531F01100AFEB9\/datafile\/o1_mf_undotbs1_fpjbvo4c_.dbf\r\nlrwxrwxrwx. 1 oracle dba 155 Aug  6 16:17 o1_mf_system_fpjp2w7z_.dbf -&gt; \/u00\/app\/oracle\/oradata\/.ACFS\/snaps\/72C5EDFE41727F36E0531F01100AB18B\/CDB\/prod_seed\/CDB\/72C340E0CEE355E1E0531F01100AFEB9\/datafile\/o1_mf_system_fpjbvnyh_.dbf\r\nlrwxrwxrwx. 1 oracle dba 155 Aug  6 16:17 o1_mf_sysaux_fpjp2wc4_.dbf -&gt; \/u00\/app\/oracle\/oradata\/.ACFS\/snaps\/72C5EDFE41727F36E0531F01100AB18B\/CDB\/prod_seed\/CDB\/72C340E0CEE355E1E0531F01100AFEB9\/datafile\/o1_mf_sysaux_fpjbvo3z_.dbf\r\n<\/pre>\n<p>so oracle &#8220;tells&#8221; the storage (in this case the ACFS driver) to do a snapshot of these data files (and only these files, if there are other databases on this acfs volume they won&#8217;t be inside the snapshot), afterwards these snapshots are linked to the location where the data files of the new clone database should be &#8211; thats it&#8230; very easy and the dba has not to worry about storage snapshots, it&#8217;s done automatically. If you drop the clone the snapshot will also be deleted automatically.<\/p>\n<p>just tell me if you have any questions&#8230;<\/p>\n<p>Benjamin<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every DBA know&#8217;s the situations, where your boss \/ customer ask you to copy fresh data into the test database&#8230; since this blog is about oracle databases, we are solving this issue usually either with &#8220;datapump&#8221; or &#8220;rman duplicate&#8221; &#8211; &hellip; <a href=\"https:\/\/blog.kurschies.de\/index.php\/2018\/08\/06\/fast-provisioning-with-snapshot-clones\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[10,11,13,7,12],"class_list":["post-297","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-acfs","tag-asm","tag-multitenant","tag-oracle","tag-snapshot"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8m6YC-4N","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/posts\/297","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/comments?post=297"}],"version-history":[{"count":27,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/posts\/297\/revisions"}],"predecessor-version":[{"id":350,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/posts\/297\/revisions\/350"}],"wp:attachment":[{"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/media?parent=297"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/categories?post=297"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kurschies.de\/index.php\/wp-json\/wp\/v2\/tags?post=297"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}