<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Orange’ Baitoey on Medium]]></title>
        <description><![CDATA[Stories by Orange’ Baitoey on Medium]]></description>
        <link>https://medium.com/@kulico_?source=rss-b8e4f73cd54f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*WrBuk7EHWXuLAt0u.</url>
            <title>Stories by Orange’ Baitoey on Medium</title>
            <link>https://medium.com/@kulico_?source=rss-b8e4f73cd54f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 10:34:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kulico_/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Work From Home เหงาๆ มาเล่น Data Redaction บน EDB Postgres กันดีกว่า]]></title>
            <link>https://medium.com/sirisoft/work-from-home-%E0%B9%80%E0%B8%AB%E0%B8%87%E0%B8%B2%E0%B9%86-%E0%B8%A1%E0%B8%B2%E0%B9%80%E0%B8%A5%E0%B9%88%E0%B8%99-data-redaction-%E0%B8%9A%E0%B8%99-edb-postgres-%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%94%E0%B8%B5%E0%B8%81%E0%B8%A7%E0%B9%88%E0%B8%B2-5bcccac38a28?source=rss-b8e4f73cd54f------2</link>
            <guid isPermaLink="false">https://medium.com/p/5bcccac38a28</guid>
            <category><![CDATA[pdpathailand]]></category>
            <category><![CDATA[enterprisedb]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[redaction]]></category>
            <dc:creator><![CDATA[Orange’ Baitoey]]></dc:creator>
            <pubDate>Wed, 30 Jun 2021 11:14:08 GMT</pubDate>
            <atom:updated>2021-06-30T12:00:54.646Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o8rRbaAkF4fADQY_LErJuA.png" /><figcaption>Work From Home เหงาๆ มาเล่น Data Redaction บน EDB Postgres กันดีกว่า</figcaption></figure><p>สวัสดีค่าา ทุกคน ยังจำหน่องเตยคนนี้กันได้มั้ยเอ่ยยย กลับมาพบกันในรอบปีอีกแล้ว คราวนี้หน่องเตย จะชวนทุกคนมาลองเล่น Feature Data Redaction บน Database ค่าย EDB Postgres กันค่ะ… ขอเสียงสาวก Database Postgres หน่อยค่าาา วู้วววๆ :D</p><p>สำหรับใครที่ยังงงว่า เอ๊ะ! Postgres กับ EDB Postgres นี่มันเหมือนกันหรือเปล่านะ !?</p><p>ทางนี้มีคำตอบให้ค่าา ❤ ใครที่คุ้นเคยกับ Postgres อยู่แล้ว ก็จะทราบกันดีว่า <strong>Postgres เป็น Database open source ใน ฉายาที่ว่า “The World’s Most Advanced Open Source Relational Database” ที่ร่วมพัฒนาโดย developer ที่ทราบกันในชื่อ PostgreSQL Global Development Group </strong>เป็นที่นิยมใช้กันอย่างแพร่หลาย ทั้งระบบเล็กๆ ไปจนถึงองค์กรใหญ่ๆ ที่มี transaction ตลอดทั้งวัน โดย Logo ของเค้าจะเป็น คุณช้างสีฟ้ามีงา น่ารักสุดๆ แบบนี้เลยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Rf2QGz4GQaP6bNZ_rJCr5Q.png" /><figcaption>PostgreSQL</figcaption></figure><p>ส่วนเจ้า <strong>EDB Postgres จะเป็น Database ที่มีการทำงาน base on Postgres แต่เพิ่มความเป็น Enterprise เข้ามาได้แก่ Security, Productivity, Performance และ Oracle database compatibility ค่ะ</strong> นอกจากนี้ ยังมี subscription ในการเปิดเคส support issue กับทีมงานที่มีความเชี่ยวชาญด้าน Postgres ด้วยนะคะ ใครที่เคยเจ็บหัวใจกับการแก้เคส Postgres โดยไม่มีที่ปรึกษา และ knowledge center น่าจะถูกใจมากๆ เลยล่ะค่ะ ส่วน Logo ของ EDB จะเป็นคุณช้างสีส้ม โมเดิร์นๆ แบบนี้เลยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*q8wqJEkhm7DmmvyJFi2Bug.png" /><figcaption>EDB Postgres</figcaption></figure><p>เกริ่นมาพอสมควร ขอเข้าเรื่องเลยแล้วกันนะคะ เนื่องจากกระแส การใช้งาน Database Postgres เริ่มมีมากขึ้นในทุกปี รวมถึงบางองค์กรเริ่มเห็นถึงความสำคัญด้าน Security มากขึ้นตามกฎหมายคุ้มครองข้อมูลส่วนบุคคล (PDPA) จึงได้เริ่มขยับขยายมาใช้งาน EDB Postgres กันบ้างเพื่อให้ครอบคลุม ด้าน Security ในราคา subscription ที่น่ารัก วันนี้หน่องเตยเลยเลือก feature ด้าน security อย่าง Data Redaction มาเล่นให้ดูกันค่ะ มาดูกันเล้ยยยย GO! GO! GO!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VVRh14fICu-wbvQbQi2RUg.png" /></figure><p>Demo วันนี้หน่องเตยมี environment ที่เป็น EDB Postgres 2 เครื่อง set replicate ข้อมูลกันอยู่ แต่การ configure redaction จะทำที่เครื่อง Master เท่านั้นค่ะ<br>Master hostname: edb-postgres<br>Slave hostname: edb-postgres-slave<br>โดยจะมี 5 ขั้นตอนง่ายๆ ตามนี้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O9rQZvCDLofVsirXOyEGsA.png" /><figcaption>5 Steps for EDB Postgres data redaction</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d0e9lDRy-HP7M0p6DVu4-Q.png" /><figcaption>Enable edb_data_redaction parameter</figcaption></figure><p>เริ่มจากต้องตรวจสอบการเปิด Feature Redaction ที่ parameter edb_data_redaction ในไฟล์ postgresql.conf</p><p>ตรวจสอบ parameter จากคำสั่งใน psql</p><blockquote>Show edb_data_redaction;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/415/1*Tw-B2la45h56AcUMza0AVA.png" /><figcaption>ตรวจสอบ parameterจากคำสั่งใน psql</figcaption></figure><p>ตรวจสอบ parameter จากไฟล์ postgres.conf ที่ path data</p><blockquote>cat postgresql.conf |grep edb_data_redaction</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/1*yozMW5on6YsNnMun0Ftt2g.png" /><figcaption>ตรวจสอบ parameter จากไฟล์ postgres.conf ที่ path data</figcaption></figure><p>โดยปกติแล้ว ค่า Default ของ parameter edb_data_redaction จะ enable ไว้ ซึ่งเมื่อมี<strong>การตั้ง redaction policy จะมีผล redaction ได้เฉพาะ user ที่ match กับ policy condition ยกเว้น Superusers และ table owner ที่จะถูก bypass data redaction และจะยังเห็น Original data</strong> ได้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HKwqjsIS2Ng1AvGNcluveA.png" /><figcaption>Create or choose table with sensitive data</figcaption></figure><p>เมื่อ enable parameter เรียบร้อยแล้ว จะเข้าสู่ database ด้วย user enterprisedb ซึ่งเป็น superuser ของ database</p><p>ตรวจสอบ connection information ของ user enterprisedb</p><blockquote>\conninfo<br>\du enterprisedb</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/887/1*BSev-n-MggVhZNU2qw5Wnw.png" /><figcaption>ตรวจสอบ connection information ของ user enterprisedb</figcaption></figure><p>ขั้นตอนนี้ให้ เลือก table ที่มี sensitive data มาค่ะ แต่เนื่องจากเป็น demo หน่องเตยขอสร้าง table ขึ้นมาใหม่นะคะ</p><p>ทำการสร้าง table ตัวอย่างในการทำ redaction</p><blockquote>CREATE TABLE edb_redaction_tab (<br>id_card varchar(17) NOT NULL,<br>first_name varchar(40) NOT NULL,<br>last_name varchar(40) NOT NULL,<br>phone varchar(10),<br>birthday date,<br>salary money,<br>email varchar(100));</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/485/1*Gws1Z1Dt3t-cFsLTIU4yMQ.png" /><figcaption>ทำการสร้าง table ตัวอย่างในการทำ redaction</figcaption></figure><p>ทำการ Insert ข้อมูลตัวอย่างที่มี Sensitive data</p><blockquote>INSERT INTO edb_redaction_tab (id_card, first_name, last_name, phone, birthday, salary, email) VALUES<br>( ‘1–1234–56789–01–2’, ‘Thongjai’, ‘Saisom’, ‘0961234567’, ‘19-Jun-1984’,84550.25, ‘thongjai.s@srs.com’),<br>( ‘3–1267–84989–03–9’, ‘Manita’, ‘Chujai’, ‘0871234567’, ‘2-Jan-1990’, 65750.00,’manita.c@srs.com’),<br>( ‘1–3214–88079–05–7’, ‘Samachet’, ‘Ketsuwan’, ‘0631234567’, ‘15-Nov-1994’, 44500.00, ‘samachet.k@srs.com’);</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fBO9ZRl27n2CNglzbFbNOQ.png" /><figcaption>ทำการ Insert ข้อมูลตัวอย่างที่มี Sensitive data</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SvudPYxKYhgFtOjiRwUSIw.png" /><figcaption>Create user or choose user with privilege on the table</figcaption></figure><p>ขั้นตอนนี้ให้เลือก user ที่ต้องการจัดการสิทธิ์ในการดูข้อมูล หรือต้องการ ปกปิดข้อมูล</p><p>ใน Demo นี้จะทำการสร้าง user ตัวอย่าง 2 users โดยจะตั้ง redaction ให้ user hr มีสิทธิ์ในการเห็น sensitive data และ user app_adm มีสิทธิ์เห็นเพียงข้อมูลบางส่วนของ table</p><blockquote>CREATE USER hr;<br>alter user hr password ‘welcome1’;<br>CREATE USER app_adm;<br>alter user app_adm password ‘welcome1’;</blockquote><p>ให้สิทธิ์ 2 users สามารถใช้งาน table ตัวอย่าง</p><blockquote>GRANT ALL ON edb_redaction_tab TO hr, app_adm;</blockquote><p>ตรวจสอบ Privilege บน table ตัวอย่างที่ Grant ให้กับ 2 users</p><blockquote>SELECT * FROM information_schema.role_table_grants <br>WHERE table_name=’edb_redaction_tab’ and grantee in (‘hr’,’app_adm’);</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tryHUoL3uCjiznk5vETl0A.png" /><figcaption>ทำการสร้าง user และให้สิทธิ์ใช้งาน table ตัวอย่าง</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z6ztv9sNuri5rbC4bX2MOQ.png" /><figcaption>Create function for redaction</figcaption></figure><p>ทำการสร้าง Redaction function ตาม column ที่ต้องการปกปิกข้อมูล sensitive data โดย demo นี้ทำ 3 columns คือ id_card, phone, salary</p><blockquote>CREATE OR REPLACE FUNCTION <strong>myredact_id_card</strong> (id_card varchar(17)) RETURN varchar(17) IS<br>BEGIN<br>/* replaces 1–1234–56789–01–2 with 1-xxxx-xxxx9–01–2 */<br>return overlay (id_card placing ‘xxxx-xxxx’ from 2) ;<br>END;</blockquote><blockquote>CREATE OR REPLACE FUNCTION <strong>myredact_phone</strong> (phone varchar(10)) RETURN varchar(10) IS<br>BEGIN<br>/* replaces 0961234567 with 096xxxx567 */<br>return overlay (phone placing ‘xxxx’ from 4) ;<br>END;</blockquote><blockquote>CREATE OR REPLACE FUNCTION <strong>myredact_salary</strong> () <br>RETURN money IS <br>BEGIN <br>return 0::money; <br>END;</blockquote><p>ตรวจสอบ Function ที่สร้างสำเร็จ</p><blockquote>select proname,prosrc from pg_proc where proname like ‘<strong>myredact%’</strong>;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*g4KV4vIkmdb8Y9YtHZ6h5Q.png" /><figcaption>ทำการสร้าง Redaction function ตาม column ที่ต้องการปกปิกข้อมูล sensitive data</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3-XD_kCvg3M6Qucc0LaUCA.png" /><figcaption>Create policy using function redaction</figcaption></figure><p>ทำการสร้าง Policy Redaction จาก Function ที่สร้างไว้ โดยให้เงื่อนไขว่า user ที่ไม่ใช้ hr (และ superuser) ถูกปกติปิดข้อมูลตาม policy</p><blockquote>CREATE REDACTION POLICY myredact_personal_data ON edb_redaction_tab FOR (s<strong>ession_user != ‘hr’</strong>)</blockquote><blockquote>ADD COLUMN id_card USING myredact_id_card(id_card) WITH OPTIONS (SCOPE query, EXCEPTION equal),</blockquote><blockquote>ADD COLUMN phone USING myredact_phone(phone) WITH OPTIONS (SCOPE query, EXCEPTION equal),</blockquote><blockquote>ADD COLUMN salary USING myredact_salary() ;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/926/1*mw4PsNbQDsuLsYxDIRfS6g.png" /><figcaption>ทำการสร้าง Policy Redaction จาก Function ที่สร้างไว้</figcaption></figure><p>ตรวจสอบ redaction policy ที่สร้างสำเร็จ</p><blockquote>Select * from edb_redaction_policy;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8nWpiBPnxAMUtt-1bMqerw.png" /><figcaption>ตรวจสอบ redaction policy ที่สร้างสำเร็จ</figcaption></figure><p>หลังจากสร้าง Policy เสร็จแล้ว ก็ไปลอง Test กันเลยค่าาาา เริ่มจากการทดสอบบนเครื่อง Master กันก่อนเลย</p><ol><li>เข้า database ด้วย user enterprisedb (superuser, table owner) จะเห็นข้อมูล original ใน table</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*URSvjKLVdauhZyrx89MY3g.png" /><figcaption>enterprisedb (superuser, table owner) จะเห็นข้อมูล original</figcaption></figure><p>2. เข้า database ด้วย user hr (privilege user) จะเห็นข้อมูล original ใน table</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4qHbyAfiQDQctGGd5ChUjw.png" /><figcaption>user hr (privilege user) จะเห็นข้อมูล original ใน table</figcaption></figure><p>3. เข้า database ด้วย user app_adm (non-privileged user) จะเห็นข้อมูล sensitive data ถูก redaction ใน table</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*qFNaGKnEFJYTadfNCF91bw.png" /><figcaption>user app_adm (non-privileged user) จะเห็นข้อมูล sensitive data ถูก redaction ใน table</figcaption></figure><p>มาถึงการทดสอบบนเครื่อง Slave ที่ replicate data ไว้ ก็ได้รับ replicate policy ด้วยเช่นกันค่ะ ทำให้ user app_adm ที่เข้าเครื่อง Slave ถูกปกปิดข้อมูล sensitive ด้วยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*dswettBIQM627Y922id3sw.png" /><figcaption>เครื่อง Slave ที่ replicate data ไว้ ได้รับ replicate policy เช่นกัน</figcaption></figure><p>เป็นยังไงกันบ้างคะ 5 steps ง่ายๆ ก็ได้ redaction policy มาป้องกันข้อมูล sensitive data แล้วค่ะ</p><blockquote>Note ไว้หน่อยนึงนะคะ เรื่องข้อจำกัดของการทำ data redaction</blockquote><blockquote>- Redaction Policy ที่สร้างใช้กับ table ที่เป็น inheritance hierarchies (parent table) จะไม่สามารถสืบทอดไปใช้กับ child table ได้ ทำให้ user ที่ access ผ่าน child table ยังสามารถเรียกดู original data ได้</blockquote><blockquote>- Redaction Policy ไม่สามารถสืบทอดไปยัง Materialized view ของ table ได้ ถ้าหาก superuser หรือ table owner ได้ GRANT SELECT on table และ materialized view ให้กับ non-superuser ทำให้ user คนนั้นสามารถเรียกดู original data ได้ผ่าน materialized view</blockquote><blockquote>- Objects ที่เกี่ยวข้องใน redaction function ต้องมีการใส่ schema ที่เป็น owner กำกับไว้ หากไม่ใส่อาจส่งผลให้การทำ pg_dump operation fail ได้ค่ะ</blockquote><p>นอกจากตัว Feature Data Redaction ที่ลองมาเล่นให้ดูกันแล้ว ทาง EDB Postgres ก็ยังมีอีกหลาย Feature ด้าน security ที่เพิ่มความเป็น enterprise มากขึ้นให้กับ Postgres ทุกคนสามารถไปลองศึกษาและลองเล่นกันดูได้นะคะ list feature ด้าน security มีดังนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*19s9iGGTDrR4IWP9iBvwQA.png" /><figcaption>EDB Postgres Security Features</figcaption></figure><p>สำหรับชาว Medium หลายคนที่ตอนนี้น่าจะ Work From Home กันยาวๆ มาตั้งแต่ช่วงต้นปี ด้วยสถานการณ์ Covid-19 ในบ้านเราช่วงนี้ ยังไงก็ขอให้ทุกคนรักษาตัวกันให้ดีนะคะ ด้วยความห่วงใย จากใจดวงน้อยๆของหน่องเตย ❤</p><p>ถ้าอยู่บ้านกันเหงาๆ ลองเล่น Database EDB Postgres กันดูได้นะคะ :D</p><p>❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FsgQTk6DxNv_Qbj6_GIeuQ.png" /></figure><p>สำหรับผู้ที่สนใจติดต่อทีมงาน DBA ( Database Administrator) ไปช่วยตรวจสอบและดูแลระบบของท่าน ไม่ว่าจะเป็น<br>- ต้องการผู้ช่วยตรวจสอบปัญหา Database<br>- ต้องการผู้ช่วยดูแลระบบ Database ขององค์กร <br>- ต้องการย้ายระบบ และต้องการคำปรึกษาด้านการออกแบบระบบฐานข้อมูล<br>- ต้องการทำ Database Security <br>- ต้องการปรึกษาเรื่อง Tool Database Security หรือ Tool ในการ Monitor ระบบ <br>และอีกหลากหลายบริการด้าน Database</p><p>สามารถติดต่อมาที่ Facebook <a href="https://www.facebook.com/sirisoft/">Sirisoft</a> <br>ทาง website <a href="http://www.sirisoft.co.th/">www.sirisoft.co.th</a> <br>หรือทาง <a href="https://lin.ee/1eqbK9V">LINE Sirisoft Official</a> ได้นะคะ</p><p>ทางเรามีทีมงาน DBA ที่พร้อมให้บริการด้าน Database Oracle, MSSQL, PostgreSQL, EDB Postgres เสมอค่ะ</p><p>ติดต่อมาได้เลยน้าา ทีมงานพร้อมจะดูแลทุกท่านค่าาา</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jp2rQnITlmeMqkeZMCVI0Q.png" /><figcaption>reference cute icon from <a href="https://www.flaticon.com/">https://www.flaticon.com</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5bcccac38a28" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sirisoft/work-from-home-%E0%B9%80%E0%B8%AB%E0%B8%87%E0%B8%B2%E0%B9%86-%E0%B8%A1%E0%B8%B2%E0%B9%80%E0%B8%A5%E0%B9%88%E0%B8%99-data-redaction-%E0%B8%9A%E0%B8%99-edb-postgres-%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%94%E0%B8%B5%E0%B8%81%E0%B8%A7%E0%B9%88%E0%B8%B2-5bcccac38a28">Work From Home เหงาๆ มาเล่น Data Redaction บน EDB Postgres กันดีกว่า</a> was originally published in <a href="https://medium.com/sirisoft">Sirisoft</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Basic Database Performance Monitoring ฉบับออกรบด้วยมือเปล่า*]]></title>
            <link>https://medium.com/sirisoft/basic-database-performance-monitoring-%E0%B8%89%E0%B8%9A%E0%B8%B1%E0%B8%9A%E0%B8%AD%E0%B8%AD%E0%B8%81%E0%B8%A3%E0%B8%9A%E0%B8%94%E0%B9%89%E0%B8%A7%E0%B8%A2%E0%B8%A1%E0%B8%B7%E0%B8%AD%E0%B9%80%E0%B8%9B%E0%B8%A5%E0%B9%88%E0%B8%B2-d57a2f1a28be?source=rss-b8e4f73cd54f------2</link>
            <guid isPermaLink="false">https://medium.com/p/d57a2f1a28be</guid>
            <category><![CDATA[database-administration]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[monitoring]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[oracle]]></category>
            <dc:creator><![CDATA[Orange’ Baitoey]]></dc:creator>
            <pubDate>Thu, 07 May 2020 09:08:47 GMT</pubDate>
            <atom:updated>2020-05-07T09:58:59.014Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7XPVpO47fGlSZ2cNe3QgcQ.png" /><figcaption>Basic Database Performance Monitoring ฉบับออกรบด้วยมือเปล่า*</figcaption></figure><p>สวัสดีค่ะ ทุกคน กลับมาพบกับหน่องเตยอีกแล้วนะคะ Blog นี้เป็น Blog ที่ 4 ของหน่อยเตยแล้วน้า ขอบคุณมิตรรักแฟน Blog Medium ทุกท่านที่ยังเหนียวแน่นแวะเวียนเข้ามาด้วยนะคะ ส่วนใครตกรถ มาไม่ทัน ไปตามอ่านย้อนหลังกันได้ <a href="https://medium.com/@kulico_">ที่นี่</a> เลยค่ะ</p><p>เข้าเรื่องกันดีกว่า.. หน่องเตยมาวันนี้ ก็ต้องมีเรื่องดี๊ดีย์ มานำเสนอให้ทุกคนแน่นอนค่ะ นั่นก็คืออออออ การ Monitor Oracle Database Performance นั่นเองงงง :3</p><p>เหตุผลที่เราควรจะ Monitor Database Performance นั้น ก็เป็นเพราะว่าเราต้องคอยตรวจสอบการทำงานของระบบ Database ในช่วงเวลาที่ User มีการใช้งานเยอะ หรือที่เรียกว่าช่วง Peak เพื่อจะได้ประเมิน Resource ของระบบ ว่าเพียงพอต่อการใช้งานหรือไม่</p><p>ซึ่งหากในช่วง Peak ที่เรา Monitor อยู่นั้นมีการทำงานของระบบที่ดูผิดปกติ เราจะได้ตรวจสอบและแก้ไขปัญหาได้ทัน ลดโอกาสระบบฐานข้อมูลล่ม ซึ่งอาจเป็นสาเหตุหนึ่งของการที่ Website หน้าบ้านไม่สามารถใช้งานได้ ด้วยนะคะ</p><p>โดยปกติ การ Monitor หรือ Diag ปัญหา เราจะต้อง Focus เส้นทางการทำงานของระบบนั้นๆ ตั้งแต่ Application &gt; Network &gt; OS &gt; Database ซึ่งในวันนี้ หน่องเตยจะขอตัดตอนมา Focus ที่ Database level กันนะคะ เพราะ Database Retrieve ข้อมูลไว ก็มีชัยไปกว่าครึ่งแล้วค่ะ :D</p><p>4 จุด เบื้องต้น ในการเริ่ม Monitoring Database มีดังนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/895/1*qjJapM5KX_8ThsrJdFXN2w.png" /><figcaption>4 Points of Starting Database Monitoring</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/802/1*aD1hgsolwNNpnQSRod3J7Q.png" /><figcaption>Database Alert log</figcaption></figure><ol><li>Database Alert log</li></ol><p>Alert log ของ Database นั้นนับว่าเป็นไฟล์ที่ค่อนข้างมีความสำคัญมากค่ะ เพราะ Database จะ Logging ข้อมูลที่เกิดขึ้นใน Database เช่น Error ต่างๆของระบบ, การเกิด Deadlock, Log ระหว่างการ Start up-Shut down Database รวมถึง Statement การ Drop, Create, Alter ต่างๆภายในระบบ</p><p>โดยเราสามารถหาไฟล์ Alert log ได้จาก</p><blockquote>$ORACLE_BASE/diag/rdbms/&lt;dbname&gt;/&lt;SID&gt;/trace/alert_&lt;SID&gt;.log</blockquote><p>หรือสามารถ query เพื่อดู path ของ alert log ด้วยคำสั่ง</p><blockquote>select * from v$diag_info;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/933/1*paC46Xc6MWvzvSHnq6VH2g.png" /><figcaption>path ของ alert log</figcaption></figure><p>เมื่อเข้าไปที่ Path /u01/app/oracle/diag/rdbms/kulicodb/kulicodb/trace ก็จะเปิดไฟล์ alert_&lt;SID&gt;.log ซึ่งสามารถช่วยเราในการ Diag ปัญหาหรือเห็นความผิดปกติของระบบที่เกิดขึ้นใน Alert log ได้ ตัวอย่างข้อมูลในไฟล์ ดังรูปต่อไปนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*HfBdsYLbEVnYHVupkvbCYw.png" /><figcaption>ตัวอย่างข้อมูลในไฟล์ Database alert log</figcaption></figure><p>ถ้า Database ของเรามีปัญหา อาจจะสังเกตได้จาก Error Code ที่ขึ้นอยู่ใน Alert log ค่ะ อย่างเช่น ORA-00020: maximum number of processes (400) exceeded ดังรูปนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*5CoUkKc7qauiXqpVlnhpxw.png" /><figcaption>ตัวอย่าง Error Code ในไฟล์ Database alert log</figcaption></figure><p>จากรูปตัวอย่างนี้ Error ตัวนี้ มีผลทำให้ User ไม่สามารถ Connect Database ได้เนื่องจาก Process เต็ม ก็จะเป็นข้อมูลให้เราวิเคราะห์ต่อไปได้ว่า ระบบมีจำนวนผู้เข้าใช้งานเพิ่มขึ้นจริง, การเขียน Logic ของ Application ที่ยิงเข้ามาไม่ถูกต้อง, ถูกก่อกวนโดยผู้ไม่หวังดี หรืออาจเป็นที่การตั้งค่า Parameter ไม่เหมาะสมกับการใช้งานจริง จากนั้นจึงหาวิธีการแก้ไขปัญหานี้ต่อไปค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*Zs3pMnie23gLcmZW42cYmQ.png" /><figcaption>Database Cache</figcaption></figure><p>2. Database Cache</p><p>การ Monitor Database Cache นั้นเป็นการตรวจสอบความเพียงพอต่อการใช้งานในส่วน Memory ที่ได้ Allocate ให้กับ Database ค่ะ ถ้าใครทำงานสาย DBA จะทราบกันดีเรื่อง Memory Component ภายใน Database Instance ตามรูปนี้เลยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/898/1*4RNbN9vg4V6rX_9d9et-Sw.png" /><figcaption>SGA Components</figcaption></figure><p>วันนี้จะขอพูดถึงส่วนของ Cache ใน Memory นะคะ ที่ประกอบไปด้วย Cache หลักๆ ดังนี้</p><p>❤ DB Buffer Cache: เป็น Memory cache ส่วนที่เก็บ Data ที่ถูก Retrieve จาก Physical ไฟล์ขึ้นมาไว้บน Memory</p><p>❤ Library Cache: เป็น Memory cache ส่วนย่อยของ Share pool ที่ใช้สำหรับเก็บ SQL Statement และ Objects ที่ถูกเรียกใช้ขึ้นมาไว้บน Memory</p><p>❤ Data Dictionary Cache: เป็น Memory cache ส่วนย่อยของ Share pool ที่เก็บข้อมูล Database Table, View, Structure และ ข้อมูล User จะถูก Access บ่อยๆ เมื่อมี SQL Statement Executes บน Database</p><p>ซึ่งวิธีการ Monitor Cache นั้นก็จะเป็นการ Select ค่า Cache Hit Ratio ขณะที่ระบบมีการใช้งานอยู่ เพื่อตรวจสอบว่า Cache มีขนาดเพียงพอในการเก็บข้อมูลที่ถูกเรียกใช้บ่อยหรือไม่ค่ะ โดยใช้คำสั่ง</p><blockquote>SELECT ‘DB_Buffer_Cache_Hit_ratio ‘<br>||round(100*(1 — (physical_reads / (db_block_gets + consistent_gets))),2) <br>|| ‘%’ AS “Cache Hit Ratio [%]” <br>FROM v$BUFFER_POOL_STATISTICS<br>union all<br>SELECT ‘Library_Cache_Hit_ratio ‘<br>||round(100*(sum(pinhits)/sum(pins)),2) <br>|| ‘%’ AS “Cache Hit Ratio [%]” <br>FROM v$LIBRARYCACHE<br>union all<br>SELECT ‘Dictionary_Cache_Hit_ratio ‘<br>||round(100*(1-(sum(getmisses)/sum(gets))),2) <br>|| ‘%’ AS “Cache Hit Ratio [%]” <br>FROM v$ROWCACHE;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/526/1*zEiBTzMur61p0hQAnqqhYw.png" /><figcaption>Database Cache Hit Ratio</figcaption></figure><p>โดยค่า Hit Ratio ที่ได้ควรมีค่า 95–100% หมายความว่า Retrieve Data ได้จาก Cache (Cache Hit) เลย ไม่ต้องไปดึงจาก Physical File นั่นหมายความว่า ระบบ Return ข้อมูลได้ไวค่ะ แต่ถ้าหากค่าที่ได้น้อยกว่า 95% ต้องมาพิจารณาการใช้งานแล้วค่ะ ว่าระบบนี้ได้ Allocated Memory และ แบ่ง Pool ต่างๆใน SGA ไว้พอใช้หรือเปล่า หรือมีสาเหตุอื่นร่วมด้วยหรือเปล่า ซึ่งจะเป็นเรื่องของการ Tuning Memory Parameter ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*Wtd4naFFzk6tBZ7DLLP5Iw.png" /><figcaption>Database Session</figcaption></figure><p>3. Database Session</p><p>การ Monitor Database Session แบบพื้นฐาน หน่องจะใช้วิธีเข้าไป Select Session ดูจากใน Database เลยค่ะ โดย Query จาก View v$session ซึ่งสามารถดูจำนวน Session ได้แบบ Real-Time เลยค่ะ โดยใช้ Query ดังนี้</p><blockquote>select sid,serial#,username, program, machine,osuser, inst_id, count(*)</blockquote><blockquote>from gv$session where username is not null</blockquote><blockquote>group by sid,serial#,username, program, machine, inst_id, osuser</blockquote><blockquote>order by 6;</blockquote><p>ก็จะพบกับข้อมูล ของ Session ที่ต่อเข้ามาที่ Database ถ้าเป็นระบบที่ Implement แบบ RAC ที่ column INST_ID จะเป็นตัวบอกว่า Session นั้นๆ ต่อไปที่ Instance ไหนด้วยค่ะ ซึ่งตรงนี้จะช่วยให้เราตามสืบได้ ว่า SID ไหนเป็นตัวการทำให้ CPU ของ Database Instance ขึ้นสูงได้ด้วยนะคะ อิอิ ตัวอย่าง Session ตามรูปด้านล่างนี้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p-A-d-w_D6iyPPJXJw4fmQ.png" /><figcaption>Monitor Database Session</figcaption></figure><p>และหากต้องการตรวจสอบว่ามี Query Lock กันอยู่ เป็นสาเหตุให้เกิด Blocking session และมี wait หรือเปล่า สามารถใช้คำสั่งต่อไปนี้เพื่อตรวจสอบได้เลยค่ะ</p><blockquote>SELECT <br>DECODE (l.BLOCK, 0, ‘Waiting’, ‘Blocking -&gt;’) user_status<br>,CHR (39) || ses.SID || ‘,’ || ses.serial# || CHR (39) sid_serial<br>,(SELECT instance_name FROM gv$instance WHERE inst_id = l.inst_id) conn_instance<br>,ses.SID ,ses.PROGRAM ,ses.osuser ,ses.machine<br>,DECODE (l.TYPE,’RT’, ‘Redo Log Buffer’,’TD’, ‘Dictionary’,’TM’, ‘DML’,’TS’, ‘Temp Segments’,’TX’, ‘Transaction’,’UL’, ‘User’,’RW’, ‘Row Wait’,l.TYPE) lock_type<br>,DECODE (l.lmode,0, ‘None’,1, ‘Null’,2, ‘Row Share’,3, ‘Row Excl.’,4, ‘Share’,5, ‘S/Row Excl.’,6, ‘Exclusive’,LTRIM (TO_CHAR (lmode, ‘990’))) lock_mode<br>,ctime ,object_name<br>FROM gv$lock l JOIN gv$session ses ON (l.inst_id = ses.inst_id AND l.SID = ses.SID)<br>JOIN gv$locked_object o ON (o.inst_id = ses.inst_id AND ses.SID = o.session_id)<br>JOIN dba_objects d ON (d.object_id = o.object_id)<br>WHERE (l.id1, l.id2, l.TYPE) IN (SELECT id1, id2, TYPE FROM gv$lock WHERE request &gt; 0)<br>ORDER BY id1, id2, ctime DESC;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*PoPjF5QwttXz9VEYGHMmvA.png" /></figure><p>จากรูปก็จะเห็นข้อมูลว่า Session ไหนบ้างที่กำลัง lock กันอยู่ที่ Object ไหน ซึ่งการ lock นี้อาจเกิดจาก Query ทำงานช้าต้อง Tuning หรือเกิดจากการเรียง Sequence ของงานไม่สอดคล้องกับระยะเวลาที่ใช้ในแต่ละ Transaction อาจะเป็นตัวช่วยให้เราปรับแก้ที่ logic, sequence งานหรือหน่วงเวลาการทำงานได้ด้วยค่ะ วิธีการแก้ไขขึ้นอยู่กับความเหมาะสมของระบบด้วยนะคะ</p><p>และถ้าต้องการดูข้อมูลเพิ่มเติมว่า ณ เวลานั้นมี Statement ไหนกำลัง Running อยู่ใน Database สามารถใช้ Query ต่อไปนี้ เพื่อตรวจสอบ SQL Statement ที่ Running ณ เวลานั้น ได้เลยค่ะ</p><blockquote>select a.sid,a.serial#,a.username,a.sql_id,a.sql_child_number,optimizer_mode,hash_value,address,sql_text</blockquote><blockquote>from v$sqlarea sqlarea ,v$session a</blockquote><blockquote>where a.sql_hash_value = sqlarea.hash_value</blockquote><blockquote>and a.sql_address = sqlarea.address</blockquote><blockquote>and a.username is not null;</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JzAKDfoUNQ_5PIG9r915KA.png" /><figcaption>Monitor SQLStatement</figcaption></figure><p>ผลที่ได้ก็จะเห็นว่า มี SID อะไร กำลัง Execute Statement อะไรอยู่ และเรายังสามารถนำ SQL_ID ของ Statement นั้นไปดู Plan และ Cost ของ Statement ได้อีกด้วยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/1*PHDr-N7_7iIyhFZeRBGkFg.png" /><figcaption>Monitoring SQL Plan</figcaption></figure><p>4. Monitoring SQL Plan</p><p>วิธีการ ดู Cost ของ Statement สามารถทำได้ โดยการระบุ SQL_ID ซึ่งได้มาจากการ Monitor Session ดังนี้ค่ะ</p><blockquote>SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(‘SQL_ID’,0));</blockquote><p>จากตัวอย่าง ต้องการดู Plan และ Cost ของ Statement ‘select * from test_data;’ จะใช้คำสั่งนี้ค่ะ</p><p>SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(‘fwmbhr3bckpsa’,0));</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*M6CyVPWfot35h-Is4MAq-Q.png" /><figcaption>Monitoring SQL Plan from SQLID</figcaption></figure><p>จากรูปจะเห็น ว่า การ select * นี้ใช้วิธี Table Access Full Scan ไม่ผ่าน Index ไปที่ Table ชื่อว่า TEST_DATA พร้อมทั้งบอกจำนวน Row ที่ Select ได้และ Size ของ Data ที่ Select มาค่ะ โดยจะมีค่า Cost และ % ของการใช้งาน CPU ให้เห็นค่ะ</p><p>ตัวอย่าง Statement ที่ใช้งานจริงก็จะเห็น Plan ประมาณนี้ค่ะ ตัวอย่างด้านล่างนี้จะเห็นได้ว่ามี Condition ที่ใช้ Cost และเวลาสูง เป็นช่วงๆ ซึ่งผลให้ Elapsed time ของ Statement นี้ใช้เวลานาน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/957/1*hNkTKbr2hlNMr5DpO1VugQ.png" /><figcaption>ตัวอย่าง Plan ของ SQL Statement ที่มี Elapsed time สูง</figcaption></figure><p>และเมื่อได้ทำการ Tuning ไปนั้นทำให้ Statement นั้นมี Plan ที่เปลี่ยนไปและใช้ เวลาและ Cost ลดลงอย่างเห็นได้ชัดค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/955/1*bznKr7clkyH7bxksUKc6Gw.png" /><figcaption>ตัวอย่าง Plan ของ SQL Statement ที่ผ่านการ Tuning</figcaption></figure><p>จะเห็นได้ว่าการดู SQL Plan เป็นการช่วยให้เราเห็นว่า ที่ Condition ส่วนไหนของ Statement ที่ใช้เวลาและ Cost มาก เพื่อเป็นแนวทางในการ Tuning statement ค่ะ</p><p>และจาก 4 หัวข้อที่ผ่านมา ก็เป็นเพียงขั้นตอน “<strong>เบื้องต้น” </strong>เท่านั้น ของการตรวจสอบการทำงานของระบบค่ะ หากจะ Monitor และแก้ปัญหาอย่างจริงจัง เราจะต้องใช้ข้อมูลส่วนอื่นๆ มาประกอบการวิเคราะห์และตัดสินใจ ทั้งในฝั่ง Application, Network, และ OS ค่ะ</p><p>ซึ่งการแก้ปัญหาด้วยการ Tuning SQL Statement ก็อาจจะไม่ได้ผล 100% เสมอไปค่ะ ยังมีการปรับแก้ที่ Configuration หรือโครงสร้างการเก็บข้อมูลอีกด้วย ที่จะช่วยให้ Performance ของระบบดีขึ้น ทางที่ดี เราควรติดต่อผู้เชี่ยวชาญด้าน Database มาช่วยตรวจสอบ วิเคราะห์ปัญหากันค่ะ</p><p>❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤-❤</p><blockquote>ช่วงงง… ขายของแบบไม่เนียน ต้องไปเรียนมาใหม่</blockquote><p>สำหรับผู้ที่สนใจติดต่อทีมงาน DBA ( Database Administrator) ไปช่วยตรวจสอบปัญหา หรือช่วยดูแลระบบ Database ขององค์กร หรือต้องการย้ายระบบ ก็สามารถติดต่อมาที่ Sirisoft ได้นะคะ ทางเรามีทีมงาน DBA ที่พร้อมให้บริการด้าน Database Oracle และ MSSQL เสมอค่ะ</p><p>และสำหรับใคร ที่กำลังมองหา Tool ในการ Monitor Server อยู่นะคะ หน่องเตยอยากแนะนำ Tool ชื่อว่า Dynatrace ค่ะ เจ้า Tool นี้เป็นตัวช่วยให้เราแก้ปัญหาได้ตรงจุดมากยิ่งขึ้นและช่วยลดเวลาในการตรวจสอบของปัญหาว่าสาเหตุเกิดมาจากที่ไหน สามารถเห็นเส้นทางการทำงานของ Application ตั้งแต่การคลิกจาก Client มาเลย น่าสนใจใช่มั้ยคะ ไปลองอ่านทำความเข้าใจเจ้า Tool ตัวนี้กันได้ที่ <a href="https://medium.com/sirisoft/what-is-dynatrace-e5048616090a">Blog What is dynatrace?</a> ได้เลยค่ะ และหากสนใจสามารถสอบถามมาได้ที่ ทีมงาน Sirisoft เลยค่ะ</p><p>สุดท้ายนี้ ขอขอบคุณทุกท่านที่อ่านมาจนจบนะคะ หน่องเตยหวังว่า ทุกท่านที่แวะเวียนเข้ามาจะได้ความรู้ หรือความเข้าใจในการตรวจสอบการทำงานของระบบ Database กันมากขึ้นนะคะ แล้วพบกันใหม่ โอกาสหน้า จะมีเรื่องดี๊ดีย์ อะไรมาแชร์กันอีก กดติดตามกันไว้นะคะ ❤</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/802/1*jO1IbbzOJ8koKY2MS2toWA.png" /><figcaption>reference cute icon from <a href="https://www.flaticon.com/free-icon/cherry_740928?term=cherry&amp;page=1&amp;position=25">https://www.flaticon.com</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d57a2f1a28be" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sirisoft/basic-database-performance-monitoring-%E0%B8%89%E0%B8%9A%E0%B8%B1%E0%B8%9A%E0%B8%AD%E0%B8%AD%E0%B8%81%E0%B8%A3%E0%B8%9A%E0%B8%94%E0%B9%89%E0%B8%A7%E0%B8%A2%E0%B8%A1%E0%B8%B7%E0%B8%AD%E0%B9%80%E0%B8%9B%E0%B8%A5%E0%B9%88%E0%B8%B2-d57a2f1a28be">Basic Database Performance Monitoring ฉบับออกรบด้วยมือเปล่า*</a> was originally published in <a href="https://medium.com/sirisoft">Sirisoft</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Backup Oracle Scheduling by Jenkins]]></title>
            <link>https://medium.com/sirisoft/backup-oracle-scheduling-by-jenkins-5010f600f1a?source=rss-b8e4f73cd54f------2</link>
            <guid isPermaLink="false">https://medium.com/p/5010f600f1a</guid>
            <category><![CDATA[jenkins]]></category>
            <category><![CDATA[backup]]></category>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[linux]]></category>
            <dc:creator><![CDATA[Orange’ Baitoey]]></dc:creator>
            <pubDate>Wed, 14 Aug 2019 03:52:20 GMT</pubDate>
            <atom:updated>2020-04-16T02:57:16.210Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/919/1*9jp4rmUKjeENBNI9pj3Chw.png" /><figcaption>Backup Oracle Scheduling by Jenkins</figcaption></figure><p>สวัสดีค่ะ กลับมาพับกบ เอ้ยยย พบกับ!! หน่องเตยยยกันอีกแล้วนะคะ (กล้าเล่นนนน ) มารอบนี้เจอกันในวันฝนพรำ อย่าลืมดูแลสุขภาพกันด้วยนะคะ เข้าเรื่องกันเลยดีกว่า &gt;o&lt;”</p><p>จาก blog คราวก่อน หน่องได้แนะนำวิธีการสร้าง Database แบบ Automation โดยการสั่งผ่าน Jenkins วันนี้หน่องจะมาแนะนำวิธี Backup Oracle Database แบบง่ายเวอร์จนต้องเอามือทาบอกกันเลยทีเดียวค่ะ</p><p>รู้มั้ยคะ ว่าการ Backup Database มีความสำคัญยังไง?? แล้วทำไมเราถึงต้องมี Backup Database เก็บไว้ มาค่ะ… เดี๋ยวหน่องเตยจะเล่าให้ฟังแบบเข้าใจง๊ายยยง่ายยยยย</p><p>การ Backup Oracle Database เป็นการสำรองข้อมูลภายใน Database มาเก็บไว้ในรูปแบบของไฟล์นาม .bkp ซึ่งไฟล์ .bkp นี้จะสามารถนำกลับไป Restore ลง Database ทั้ง Database ตัวเดิม หรือ Database ตัวใหม่ เพื่อให้ได้ข้อมูลชุดเดิม ณ วันเวลาที่ทำการ Backup ไว้ ซึ่งวิธีการนี้เป็นหนึ่งวิธีที่ถูกใช้กันอย่างแพร่หลาย ในการสำรองข้อมูลค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/757/1*JSACgFricAi744kYRQA6Bw.png" /><figcaption>Database Backup Type</figcaption></figure><p>การ Backup Oracle Database มี 2 แบบดังนี้ค่ะ</p><ol><li><strong>Hot Backup</strong></li></ol><p>เป็นการ Backup Database ในขณะที่ Database เปิดอยู่ใน State Open (Database ยัง Online และสามารถใช้งานได้ปกติค่ะ) การ Backup แบบนี้ได้จะต้อง Set Archivelog Mode ให้กับ Database เพื่อสำรอง Online Redo log ของ Database ออกมาเป็น Archive log เมื่อนำไฟล์ Backup ไป Restore จะสามารถนำ Archive log มา Restore ต่อเพิ่มได้ ทำให้ได้ข้อมูลถึงปัจจุบัน</p><blockquote>ข้อดีคือ ไม่ต้องมี Downtime ให้กับ Database และข้อมูลที่ Restore ได้สามารถต่อได้ถึงปัจจุบัน หรือที่เรียกกันว่า Point In Time Recovery</blockquote><blockquote>ข้อเสียคือ ต้องมีการแบ่งพื้นที่เรียกว่า Fast Recovery Area (FRA) ไว้สำหรับเก็บไฟล์ Archive log ที่จะมีเพิ่มขึ้นตามจำนวนการใช้งานของ Database</blockquote><p><strong>2. Cold Backup</strong></p><p>เป็นการ Backup Database ในขณะที่ Database เปิดอยู่ใน State Mount (ง่ายๆ คือเป็น state ที่จะไม่มี transaction เข้า Database ค่ะเหมือนปิดการใช้งาน Database เลยล่ะ) การ Backup แบบนี้จะได้ข้อมูลเท่ากับ ณ เวลาที่เริ่ม Backup เมื่อไป Restore ก็จะได้ข้อมูลคืนกลับมาแค่ ณ เวลาที่ Backup นั้นบันทึกมาค่ะ</p><blockquote>ข้อดีคือ ไม่ต้องใช้พื้นที่ Disk เพื่อเก็บ log</blockquote><blockquote>ข้อเสียคือ มี Downtime ในขณะที่ทำการ Backup และข้อมูลที่ได้จากก้อน Backup จะไม่เป็นปัจจุบัน</blockquote><p>หลายคนอ่านมาถึงตรงนี้อาจมีคำถามใช่มั้ยคะ ว่าแล้วแบบนี้เราจะเลือก Backup Database แบบไหนดีนะ ??</p><blockquote>คำตอบก็คือ เราต้องดูลักษณะการใช้งานของ Database กันค่ะ ซึ่งโดยปกติ Database ที่ถูก Promote เป็น Production แล้วไม่ควรจะมี Downtime</blockquote><p>ดังนั้น วิธีที่หน่องเตยแนะนำคือ การ Backup Database แบบ Hot Backup นะคะ ส่วนใครที่กำลังกังวลเรื่องมีพื้นที่ Disk จำกัดจะเก็บ Archive log พอได้ยังไง ไม่ต้องกังวลไปค่ะ เราสามารถตั้ง Job Schedule ในการ Purge Archive log เราที่ไม่จำเป็นสำหรับใช้ในการ Restore แล้วออกเพื่อคืนพื้นที่ให้กับระบบได้ค่ะ</p><p>มาเริ่มกันที่ การฝาก Script Backup ให้ Jenkins ช่วย Run กันค่ะ โดยปกติการ Backup Oracle Database สามารถทำได้ทั้งแบบ</p><blockquote>* แบบ Manual โดยการ Connect ไปที่เครื่อง Oracle Database server และใช้ tool Recovery Manager (RMAN) เพื่อพิมพ์คำสั่ง Backup โดยตรง</blockquote><blockquote>* แบบ Shell Script เป็นการเขียน Script เพื่อสั่ง Backup โดยใช้การ Execute ไฟล์ Shell Script เป็นรายครั้งที่ต้องการ Backup หรือเป็นการใช้ Cron Schedule</blockquote><p>การใช้ Cron Schedule ก็นับว่าเป็นการใช้ Script แบบ Automation ในการ Backup Database ค่ะ แต่เนื่องจากบางระบบมีการจำกัดสิทธิ์การเข้าใช้งาน Cron Schedule วันนี้หน่องเตยเลยจะมาแนะนำการตั้ง Schedule Job ในการ Backup Database ผ่าน Tool Jenkins ค่ะ ง่ายจนตกใจกันไปเลยยย ก่อนอื่น หน่องเตยขออนุญาตอธิบายคำสั่ง Backup ที่ใส่ลงไปใน Script ก่อนค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/759/1*H4MYy7lCCnPbVAgHpC56qA.png" /><figcaption>Database Backup Script</figcaption></figure><p>คำสั่งใน Script ประกอบไปด้วย 4 ส่วนค่ะ</p><ol><li>การ Set ตัวแปรและ Environment Database</li></ol><p>จะ set เหมือนกันทั้งใน Script Backup Full และ Script Backup Archive</p><blockquote>#/bin/bash</blockquote><blockquote>export ORACLE_BASE=/u01/app/oracle</blockquote><blockquote>export ORACLE_HOME=/u01/app/oracle/product/18.0.0/dbhome_1</blockquote><blockquote>export ORACLE_SID=jellybear18</blockquote><blockquote>export PATH=/u01/app/oracle/product/18.0.0/dbhome_1/bin:/usr/sbin:/usr/local/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/oracle/.local/bin:/home/oracle/bin</blockquote><blockquote>g_date=`date +%d%b%Y`</blockquote><p>คำอธิบาย Script</p><p>ORACLE_BASE : ตัวแปรสำหรับเก็บ path ไปถึง Oracle Software</p><p>ORACLE_HOME : ตัวแปรสำหรับเก็บ path ไปถึง Oracle Home</p><p>ORACLE_SID : ตัวแปรเก็บชื่อ Database System ID (ชื่อ Database Instance)</p><p>PATH : ตัวแปรเก็บ Path ของ Directory ทำให้เราสามารถ Executed Directly นั้นใน Shell ได้โดยไม่ต้องใส่ Full Path</p><p>g_date : ตัวแปรเก็บค่าวันที่ ใช้ในการนำไปตั้งชื่อไฟล์เพื่อไม่ให้ไฟล์มีชื่อ ซ้ำกัน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*bnK6tdPo069X-R6ilIt9pg.png" /><figcaption>ตัวอย่าง Script Backup Full ส่วนที่ 1</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*Dui2Xpq9o-fFNinV-IzBdg.png" /><figcaption>ตัวอย่าง Script Backup Archive ส่วนที่ 1</figcaption></figure><p>2. การสร้าง Path เก็บข้อมูลไฟล์ Backup และ Log ของการ Backup</p><p>จะ Set เหมือนหรือต่างกันก็ได้ค่ะ ตาม Path ที่ต้องการให้ไฟล์ Backup ไปลงเลย ในตัวอย่างนี้หน่องเตยตั้งไว้ไม่เหมือนกันค่ะ</p><p>ตั้งค่า Path เก็บ Backup Full และ Log Backup Full ของการ Backup</p><blockquote>mkdir -p /home/oracle/backupdb/$g_date</blockquote><blockquote>g_logfile=/home/oracle/backupdb/$g_date/backup_log_`date +%d%b%Y`.log</blockquote><p>ตั้งค่า Path เก็บ Backup Archive และ Log Backup Archive ของการ Backup</p><blockquote>mkdir -p /home/oracle/backuparch/$g_date</blockquote><blockquote>g_logfile=/home/oracle/backuparch/$g_date/backup_arch_log_`date +%d%b%Y`.log</blockquote><p>คำอธิบาย Script</p><p>mkdir -p : เป็นคำสั่งบน Os สำหรับการสร้าง Folder แบบ Full Path</p><p>g_logfile : ตัวแปรเก็บค่าชื่อไฟล์ Log Backup และต่อด้วยค่าวันที่เพื่อไม่ให้ไฟล์มีชื่อ ซ้ำกัน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*45Fv-Uu2cyKEToisBclhnA.png" /><figcaption>ตัวอย่าง Script Backup Full ส่วนที่ 2</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/662/1*39icfuBbDA7F7IpfSF9J-g.png" /><figcaption>ตัวอย่าง Script Backup Archive ส่วนที่ 2</figcaption></figure><p>3. การเข้าสู่ RMAN Mode และ Synchronize Physical Backup File บน Disk กับ Logical Records ใน RMAN Repository เพื่อเตรียม Backup Database</p><blockquote>$ORACLE_HOME/bin/rman target=/ &gt;$g_logfile 2&gt;&gt;$g_logfile &lt;&lt;EOF</blockquote><blockquote>crosscheck backupset;</blockquote><p>คำอธิบาย Script</p><p>$ORACLE_HOME/bin/rman target : เป็นคำสั่งเข้าสู่ RMAN Mode โดยเข้าแบบ Full Path จากตัวแปร ORACLE_HOME เข้าไปถึง Utility RMAN</p><p>crosscheck : เป็นคำสั่งสำหรับตรวจสอบ Backup File บน Disk กับ Logical Record ของ RMAN ว่าไฟล์จริงยังมีตรงกันกับใน List File logical หรือไม่</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*G3ODeVUKvsH8oahynf8Afg.png" /><figcaption>ตัวอย่าง Script Backup Full ส่วนที่ 3</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/659/1*OTgdgKs5Ra94PHlUChrt6g.png" /><figcaption>ตัวอย่าง Script Backup Archive ส่วนที่ 3</figcaption></figure><p>4. การ Backup Database เป็นส่วนสำคัญเลยค่ะ เราจะรวบรวมคำสั่งที่ต้องการทำตาม Sequence ของคำสั่ง</p><p>4.1 การ Backup Database</p><blockquote>run {</blockquote><blockquote>sql ‘alter system archive log current’;</blockquote><blockquote>backup as backupset device type disk tag ‘FULLBACKUP’ database format ‘/home/oracle/backupdb/$g_date/data_%T_%U.bkp’;</blockquote><blockquote>backup spfile tag ‘SPFILE’ format ‘/home/oracle/backupdb/$g_date/spfile_%T_%U.bkp’;</blockquote><blockquote>backup current controlfile format ‘/home/oracle/backupdb/$g_date/ctlfile_%T_%U.bkp’;</blockquote><blockquote>}</blockquote><p>คำอธิบาย Script</p><p>sql ‘alter system archive log current’ : คำสั่ง Switch Log File ก่อนการ Backup</p><p>backup as backupset : คำสั่ง Backup Database แบบ backupset</p><p>backup spfile : คำสั่ง Backup Server Parameter File</p><p>backup current controlfile : คำสั่ง Backup Control File</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/666/1*DgRw5lCiIT8J5WkyXurs8g.png" /><figcaption>ตัวอย่าง Script Backup Full ส่วนที่ 4</figcaption></figure><p>4.2 การ Backup Archive log</p><blockquote>run {</blockquote><blockquote>sql ‘alter system archive log current’;</blockquote><blockquote>backup archivelog from time ‘sysdate-3’ until time ‘sysdate’ tag ‘LAST3DAYS_ARC’ format ‘/home/oracle/backuparch/$g_date/arc_%h_%T_%U.bkp’;</blockquote><blockquote>}</blockquote><blockquote>allocate channel for maintenance type disk;</blockquote><blockquote>delete noprompt backup of archivelog until time ‘sysdate-14’;</blockquote><blockquote>release channel;</blockquote><p>คำอธิบาย Script</p><p>sql ‘alter system archive log current’ : คำสั่ง Switch Log File ก่อนการ Backup</p><p>backup archivelog : คำสั่ง Backup Archive Log ย้อนหลัง 3 วันจากเวลาปัจจุบัน (sysdate)</p><p>allocate channel for maintenance type disk : เป็นคำสั่งจอง Channel เฉพาะสำหรับให้ RMAN ต่อไปหา Database โดยตรง</p><p>delete noprompt backup of archivelog until time ‘sysdate-14’ : เป็นคำสั่งลบ Archive ที่เกินกว่า 14 วันออก (sysdate-14)</p><p>release channel; : เป็นคำสั่งคืน resource ที่จองเป็น Channel</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/664/1*WpBhhrsKFtIQFlcBvpSuOg.png" /><figcaption>ตัวอย่าง Script Backup Archive ส่วนที่ 4</figcaption></figure><p>เมื่อเตรียม Script Backup Database และ Script Backup Archive เรียบร้อยแล้ว <br> ก็สร้างไฟล์ Script ไว้ที่เครื่อง Database Server เลยค่ะ โดยใช้คำสั่ง</p><blockquote>$ vi bkup_db.sh</blockquote><p>เพื่อสร้างไฟล์ชื่อว่า bkup_db.sh</p><p>นำคำสั่ง Backup Database ใส่ไฟล์ และ Save File</p><blockquote>$ chmod u+x bkup_db.sh</blockquote><p>เพื่อเพิ่มสิทธิ์การ Execute File bkup_db.sh</p><p>ทำเช่นเดียวกันกับ Script bkup_arch.sh โดยใส่เป็นคำสั่ง Backup Archive log</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*wVx-m7YetQqugP7-t3-tkQ.png" /><figcaption>file bkup_db.sh</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*Ywj6BpK1uGvON0Qgilnstg.png" /><figcaption>file bkup_arch.sh</figcaption></figure><p>เมื่อสร้าง Script เรียบร้อย ก็ไปตั้ง Schedule การ Backup File ที่ Jenkins กันเลยค่ะ</p><p>สำหรับคนที่ยังไม่รู้วิธีการติดตั้ง Jenkins สามารถไปอ่านข้อมูลเพิ่มเติมจาก Blog ก่อนหน้าของหน่องเตยได้เลยน้า<a href="https://medium.com/sirisoft/%E0%B8%AA%E0%B8%A7%E0%B8%B1%E0%B8%AA%E0%B8%94%E0%B8%B5%E0%B8%84%E0%B9%88%E0%B8%B0%E0%B8%97%E0%B8%B8%E0%B8%81%E0%B8%84%E0%B8%99-%E0%B8%81%E0%B8%A5%E0%B8%B1%E0%B8%9A%E0%B8%A1%E0%B8%B2%E0%B8%9E%E0%B8%9A%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%AD%E0%B8%B5%E0%B8%81%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B8%99%E0%B8%B0%E0%B8%84%E0%B8%B0-%E0%B8%A2%E0%B8%B1%E0%B8%87%E0%B8%88%E0%B8%B3%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B9%84%E0%B8%94%E0%B9%89%E0%B8%AD%E0%B8%A2%E0%B8%B9%E0%B9%88%E0%B8%A1%E0%B8%B1%E0%B9%89%E0%B8%A2%E0%B8%99%E0%B9%89%E0%B8%B2-%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B8%A1%E0%B8%B2%E0%B9%80%E0%B8%82%E0%B8%B5%E0%B8%A2%E0%B8%99-blog-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%99%E0%B8%B5%E0%B9%89-6421e0c56cd2"> จิ้มตรงนี้เล้ยยย</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/757/1*6GMJskXL2hU-CDQ8Rp-bFg.png" /><figcaption>Create Jenkins Project and set Schedule</figcaption></figure><p>ต่อจาก Blog ที่แปะ Link ไว้ข้างบนนี้นะคะ เราก็จะสร้าง Project ขึ้นมาเป็น แบบ Freestyle project</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/675/1*gkkAY67Fxs1EtMYS4LIPpQ.png" /><figcaption>Create Freestyle project on Jenkins</figcaption></figure><p>จากนั้นไปที่ส่วนของ Build แบบ Execute Shell และใส่คำสั่งในการเรียก Script Backup Database ที่เรานำไปวางไว้บนเครื่อง Database Server</p><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/oracle/backupdb/bkup_db.sh’</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-GE_vFh_lhpvidbPh2iz4w.png" /><figcaption>Build</figcaption></figure><p>จากนั้นไปที่ส่วน Build Triggers เลือก CheckBox &gt; Build Periodically เป็นส่วนในการตั้ง Schedule เพื่อให้ Jenkins Execute Script Backup Database</p><p>สามารถคลิกเครื่องหมาย คำถามทางขวามือเพื่ออ่านข้อมูลเพิ่มเติมในการตั้งเวลา</p><p>จากตัวอย่างเป็นการทดสอบตั้งเวลาให้ Execute Script Backup Database เวลา 03:50 ทุกวัน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fodcMpFOuM2vwFlqT0hJUQ.png" /><figcaption>Build Triggers</figcaption></figure><p>เมื่อกด Save ก็รอเลยจ้า เมื่อครบเวลาที่ตั้งไว้ Jenkins จะเริ่มทำงาน Execute Script Backup Database แบบอัตโนมัติเลยค่ะ มาดูกันนนนน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7x56VD2KQSqVLhT4mBVENw.png" /><figcaption>Jenkins Execute Script Backup Database</figcaption></figure><p>สามารถกดเข้าไปดู Console ของ job ที่กำลัง Run ได้ด้วยน้าา</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TVedZnueyV4BLucxu6SAKw.png" /><figcaption>Jenkins Console output</figcaption></figure><p>Job Backup เริ่ม Running แล้ววววว</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/682/1*o6xYy6RonkYR7xNHy3ktAg.png" /><figcaption>Check Backup job</figcaption></figure><p>หลังจากที่ Job ทำงานเสร็จเรียบร้อยแล้วก็ไปตรวจสอบไฟล์ Backup ที่ Path ที่เราตั้งไว้ใน Script กันค่ะ จะเห็นไฟล์ .bkp แบบในรูปเล้ยยย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/584/1*nWcRZJAYg8pZ74OlbpNqHA.png" /><figcaption>File Backup .bkp</figcaption></figure><p>เช่นเดียวกันกับ Script Backup Archive log ค่ะ สร้าง Project ขึ้นมาเป็น แบบ Freestyle project</p><p>ที่ส่วนของ Build แบบ Execute Shell ใส่คำสั่งในการเรียก Script Backup Archive log ที่เรานำไปวางไว้บนเครื่อง Database Server</p><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/oracle/backuparch/bkup_arch.sh’</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Eay0XMBnml6MoysqORzHnw.png" /><figcaption>Build</figcaption></figure><p>ที่ส่วน Build Triggers เลือก CheckBox &gt; Build Periodically ก็เหมือนเดิมเลยค่ะ โดยจะตั้ง Schedule เพื่อให้ Jenkins Execute Script Backup Archive log</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0zxHFH6mYJUhu0AvUuhe6g.png" /><figcaption>Build Triggers</figcaption></figure><p>จากตัวอย่างเป็นการทดสอบตั้งเวลาให้ Execute Script Backup Database เวลา 04:05 ทุกวัน เมื่อครบเวลาที่ตั้งไว้ Jenkins จะเริ่มทำงาน Execute Script Backup Archive log แบบอัตโนมัติ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/875/1*JoI8cpQlO7Vo-_L6BRACtQ.png" /><figcaption>Jenkins Execute Script Backup Archive log</figcaption></figure><p>จะเห็นว่าพอถึงเวลา 04:05 Job จะเริ่ม exceute ไหนนนน ตามไปดูที่ Database ซิ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/682/1*ddErG0Z_9oa5julzKQMa1w.png" /><figcaption>Check Backup Archive log job</figcaption></figure><p>ชอบจัง เวลาเห็นคำว่า Running เนี่ยยยยยย &gt;0&lt;</p><p>หลังจากที่ Backup Archive log completed แล้วก็ไปเช็คไฟล์ Backup กันซักหน่อย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/1*rRE3n_0KA7kJF7dH6q3KCg.png" /><figcaption>File Backup Archive log .bkp</figcaption></figure><p>File Backup Archive log มาแล้วจ้าาา</p><p>เห็นมั้ยคะ แค่สั่งผ่าน Jenkins แค่ 2 บรรทัดก็สามารถมี Job Backup Auto Runing ได้สบายเลย ไม่ต้องกังวลเรื่องข้อมูลสูญหาย มี backup ข้อมูลเอาไว้ก็จะอุ่นใจหน่อยๆ แต่ถ้าอยากอุ่นกายก็ใส่เสื้อกันหนาวเอานะคะ แฮร่!!</p><p>จาก File Backup Full และ Backup Archive log ที่ได้มา สามารถนำไป ใช้ Restore Database ตัวเดิมเพื่อกู้คืนข้อมูล หรือนำไป Restore ลง Database ตัวใหม่เพื่อทำเป็น environement ใหม่ที่มี Data เหมือนกันได้ค่ะ เช่นทำเครื่องเอาไว้ test โดยจำลองข้อมูลและ configuration ให้เหมือนกับ Production ที่ Backup มา</p><p>สำหรับ Blog นี้ถึงจะดู simple นิดหน่อย แต่ก็หวังว่าจะเพิ่มข้อมูลความรู้เกี่ยวกับการสำรองข้อมูลให้กับผู้อ่านได้ ไม่มากก็น้อย ไว้กลับมาพบกันใหม่ใน Blog หน้านะคะ จะเป็นเรื่องอะไร มารอลุ้นกันค่ะ สวัสดีค่ะ :3</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/754/1*8oT8yetR6nhe3hXDTCsgIw.png" /><figcaption>reference all cute icon from <a href="https://www.flaticon.com/">https://www.flaticon.com</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5010f600f1a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sirisoft/backup-oracle-scheduling-by-jenkins-5010f600f1a">Backup Oracle Scheduling by Jenkins</a> was originally published in <a href="https://medium.com/sirisoft">Sirisoft</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ติดตั้ง Database แบบ Automation คลิกเดียวรู้เรื่อง!!]]></title>
            <link>https://medium.com/sirisoft/%E0%B8%AA%E0%B8%A7%E0%B8%B1%E0%B8%AA%E0%B8%94%E0%B8%B5%E0%B8%84%E0%B9%88%E0%B8%B0%E0%B8%97%E0%B8%B8%E0%B8%81%E0%B8%84%E0%B8%99-%E0%B8%81%E0%B8%A5%E0%B8%B1%E0%B8%9A%E0%B8%A1%E0%B8%B2%E0%B8%9E%E0%B8%9A%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%AD%E0%B8%B5%E0%B8%81%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B8%99%E0%B8%B0%E0%B8%84%E0%B8%B0-%E0%B8%A2%E0%B8%B1%E0%B8%87%E0%B8%88%E0%B8%B3%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B9%84%E0%B8%94%E0%B9%89%E0%B8%AD%E0%B8%A2%E0%B8%B9%E0%B9%88%E0%B8%A1%E0%B8%B1%E0%B9%89%E0%B8%A2%E0%B8%99%E0%B9%89%E0%B8%B2-%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B8%A1%E0%B8%B2%E0%B9%80%E0%B8%82%E0%B8%B5%E0%B8%A2%E0%B8%99-blog-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%99%E0%B8%B5%E0%B9%89-6421e0c56cd2?source=rss-b8e4f73cd54f------2</link>
            <guid isPermaLink="false">https://medium.com/p/6421e0c56cd2</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[oracle-database]]></category>
            <category><![CDATA[jenkins]]></category>
            <dc:creator><![CDATA[Orange’ Baitoey]]></dc:creator>
            <pubDate>Mon, 26 Nov 2018 20:48:42 GMT</pubDate>
            <atom:updated>2018-12-04T11:28:47.864Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*43g5BvwJAzHZkWZ0R0fzJQ.png" /></figure><p>สวัสดีค่ะทุกคน กลับมาพบกันอีกแล้วนะคะ ยังจำหน่องเตยได้อยู่มั้ยน้า… หน่องเตยมาเขียน Blog แบบนี้ แสดงว่ามีอะไรดีๆ มานำเสนอนะจ๊ะ อิอิ :p</p><p>หลายๆ คนคงรู้จัก DevOps CI/CD (Continuous Integration และ Continuous Delivery/Deployment) กันใช่มั้ยคะ</p><p>DevOps เป็น Culture การทำงานที่มีหัวใจสำคัญ คือ ความสะดวกและรวดเร็วในการ Development, Test และการ Deployment ด้วยวิธีการแบบ Automation ซึ่งจะมีประโยชน์มากในการทำงานที่ต้องมีการทดสอบ แก้ไข และ release product version ใหม่อยู่บ่อยครั้ง</p><p>แต่เนื่องจากหน่องเตยเป็นสาย DBA จึงเลยอยากลองนำ หัวใจดวงน้อยๆของ devOps คือ Automation ของ DevOps มาประยุกต์ใช้กับ Database ดูบ้าง</p><p>วันนี้เลยจะขอนำเสนอการทำ Automate Create Oracle Database by Jenkins ค่ะ ชื่อตรงตัวเลย ก็คือ Install Oracle Database 18c Softwareพร้อมทั้ง Create Database แบบพร้อมใช้งานโดยใช้ tool คุณลุง Jenkins นั่นเองค่ะ</p><p>เพียงสั่งการไปที่ Jenkins คลิกเดียว ก็สามารถเนรมิต Oracle Database มาให้เราใช้บน OS Linux ได้อย่างง่ายดาย ทันใจ ทันใช้ฝุดๆ ไปเริ่มพร้อมกันที่ละ step เลยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2c85ZTDe8EAAN4fsMD_8Fw.png" /><figcaption>Software และ Technology ที่เกี่ยวข้อง</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JrfEj-6l89xWSHaelBw8eA.png" /><figcaption>Prerequisite ที่ต้องเตรียมพร้อม</figcaption></figure><p>มาทำ Prerequisite กันทีละขั้นตอนเลยจ้าาา</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GQDQyFyoO7kjgqaToE8Dlw.png" /><figcaption>set minimum RAM</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*r32xJzA6dsEjlw4aQKSoiQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H80kdAVYRKkfiqr1joeDQg.png" /><figcaption>set minimum swap memory <a href="http://imrgill.com/2011/07/13/how-to-increase-swap-size-with-out-add-new-partition.html">Read More command Click</a></figcaption></figure><blockquote># dd if=/dev/zero of=/tmp/newswap bs=8MB count=1024</blockquote><blockquote># mkswap /tmp/newswap</blockquote><blockquote># swapon /tmp/newswap</blockquote><blockquote># free -m</blockquote><blockquote># echo “/tmp/newswap swap swap defaults 0 0” &gt;&gt; /etc/fstab</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/718/1*-m_zsoIBvDow6vWYs3Zzdg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gifYQb9VHumCMzrZdZexpw.png" /><figcaption>Map Host Name กับ IP</figcaption></figure><blockquote># vi /etc/hosts</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/764/1*hZ2PXM91A-Xe92aPTdVanA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kPUqmI67ANKorB6pL75tDg.png" /><figcaption>Stop firewall</figcaption></figure><blockquote># systemctl stop firewalld</blockquote><blockquote># systemctl disable firewalld</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/702/1*wSRKAY9mS3-wxLPpL7R_ow.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A3vfqaL4yj81SkJkAsntAQ.png" /><figcaption>Install Jenkins</figcaption></figure><blockquote># wget -O /etc/yum.repos.d/jenkins.repo <a href="http://pkg.jenkins.io/redhat-stable/jenkins.repo">http://pkg.jenkins.io/redhat-stable/jenkins.repo</a></blockquote><blockquote># rpm — import <a href="http://pkg.jenkins.io/redhat-stable/jenkins.io.key">http://pkg.jenkins.io/redhat-stable/jenkins.io.key</a></blockquote><blockquote># yum install jenkins -y</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/770/1*5d1uUZgFoQNH4D3_ARLuPg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vGNApc7ufrb2YkaIl9qd7A.png" /><figcaption>start Jenkins service</figcaption></figure><blockquote># systemctl start jenkins</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/442/1*flrRVPN9rCjRC2wO-AkTcQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5F1uJG24Cd69S-uEtLB9dg.png" /><figcaption>Login Jenkins</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*a3LD-WZ8_onB_PXKbLqc4g.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L0Ni691marZ8PrQC-IdDIg.png" /><figcaption>unlock Jenkins</figcaption></figure><blockquote># cat /var/lib/jenkins/secrets/initialAdminPassword</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*8QCnxXs_veS4gU0jUDk-0Q.png" /><figcaption>จากนั้นทำการ copy password ไปกรอกผ่านหน้า website</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/747/1*KpYa0CVf0QayjSNVu5gkWQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KW1qDe8UYadVK3HCp_nkIg.png" /><figcaption>install Jenkins plugins</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/761/1*yrBSKQTSTqjXwR2vDFSRJw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*jklJ3JbZsXeSo8gtuzNv0A.png" /></figure><p>เมื่อ install plugins เสร็จก็ให้ทุกคน Create user สำหรับทำ operation ต่างๆ ผ่าน Jenkins ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/767/1*PLgZ9YuX5lhxQ4G9ctuG3g.png" /></figure><p>ส่วนนี้เป็นการกำหนด URL สำหรับการเข้าถึง Jenkins Management ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/764/1*oHNXPlzr4W9o5M89U6ySzQ.png" /></figure><p>Jenkins is ready! เย้ เย้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/765/1*ZkKr2wHkIPfSfvbRpP5LmA.png" /></figure><p>นี่ก็คือหน้าตา Dashboard ของ Jenkins ที่จะเป็นฐานบัญชาการสั่งทำงานแบบ Automation ค่ะ อิ้อิ้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/767/1*Pxp3V-1zkXUSwF9nScGYTw.png" /></figure><p>และอย่าลืม install GitHub plugins ให้กับ คุณลุง Jenkins แกด้วยนะคะ เพราะเราจะทำการ clone scripts จาก GitHub มาค่ะ โดยไปที่เมนู Manage Jenkins</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*dmx0wOXHZzAQnfFhFTuGOg.png" /></figure><p>เลือก Manage Plugins</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/769/1*x9cLKNAjNqUb4gZNIRjNKQ.png" /></figure><p>เลือกที่ Available tab และ search หา GitHub คราวนี้เตยเลือกแค่ plugin หลักๆ คือ GitHub Pull Request Coverage Status และ GitHub Integration เลือก download now and install after restart จ้าาา</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/1*3X5CKjD4aMnosI1lN8HecQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*oApqAP_w60QrvOXSyYjgqw.png" /></figure><p>เลื่อนลงมาข้างล่างแล้วเลือก เครื่องหมายถูก ให้ restart Jenkins ด้วยนะคะ เมื่อ download เสร็จก็ให้คลิก go back to the top page</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/775/1*e7qtBxFbe6mNRqs9qVePCg.png" /></figure><p>ระหว่างนี้ไป prepare step ถัดไปกันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IIONWHwcTRsTh7A8Pk1_Zw.png" /><figcaption>Transfer oracle database 18c software Zip file to node</figcaption></figure><blockquote>pscp.exe C:\Users\Suphisara\Desktop\oracle_database_18c\LINUX.X64_180000_db_home.zip root@172.20.10.3:/home/</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/873/1*A-DokrVoORr04zP0FA1pGw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/1*VOpvxjAHGSiNErj0P1APzQ.png" /><figcaption>Push script to GitHub</figcaption></figure><blockquote>git status</blockquote><blockquote>git add .</blockquote><blockquote>git status</blockquote><blockquote>git commit -m “please work”</blockquote><blockquote>git push origin master</blockquote><blockquote>login GitHub</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/581/1*UzPQIMFKy19MNWoyLbaz3w.png" /><figcaption>สามารถ clone git <a href="https://github.com/kulico/automate_install_sw_18c">คลิกที่นี่</a> และนำ script มาปรับให้เหมาะสมตาม environment ที่ต้องการใช้ได้เลยค่ะ</figcaption></figure><p>Scripts ที่ถูก push ขึ้นไปบน GitHub จ้าาาา</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/919/1*EvVe9rbXB3Zp5jqSEB3ttw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Mzxs-AVkqP8jdtkGnWF1Wg.png" /></figure><p>เลือกที่ create new jobs</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*vZ1CHks0FDXtlxy5O2qNQA.png" /></figure><p>เลือก freestyle project และตั้งชื่อ ครั้งนี้เตยจะสร้าง Project ไว้ 2 Project นะคะ</p><ol><li>Automate_Install_SW18c : สำหรับการติดตั้งครั้งแรก โดยคำสั่งภายในจะเป็นการเรียก script เพื่อ install oracle database software และสร้าง database ตัวที่ 1 ชื่อว่า jelly1</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DpQpyRDAn04W0eyOeRvLqQ.png" /><figcaption>Project : Automate_Install_SW18c</figcaption></figure><p>โดยเราจะตั้งค่าลำดับการทำงานของ Jenkins ในการเรียก Scripts แต่ละตัวจากส่วนที่เป็น Build แบบ Execute Shell และใส่คำสั่งในการเรียก scripts ดังนี้</p><blockquote>#1<br>#transfer file oracle18c.zip to /home/ <br>#by using cmd<br>#pscp.exe C:\Users\Suphisara\Desktop\oracle_database_18c\LINUX.X64_180000_db_home.zip root@172.20.10.3:/home/</blockquote><blockquote>#put all script into github<br>#by using git bash<br># git status<br># git add .<br># git status<br># git commit -m “please work”<br># git push origin master<br># login GitHub</blockquote><blockquote>#2<br>#prepare clone script from git</blockquote><blockquote>echo P@ssw0rd | su root bash -c ‘mkdir /home/git_scripts’<br>echo P@ssw0rd | su root bash -c ‘yum install git -y’<br>echo P@ssw0rd | su root bash -c ‘git clone https://github.com/kulico/automate_install_sw_18c /home/git_scripts’</blockquote><blockquote>#3<br>#prepare environment for oracle</blockquote><blockquote>echo P@ssw0rd | su root bash -c ‘sh /home/git_scripts/control_script1.sh’</blockquote><blockquote>#4<br>#Install software 18c</blockquote><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/git_scripts/runinstaller.sh’<br>echo P@ssw0rd | su root bash -c ‘sh /home/git_scripts/control_script2.sh’</blockquote><blockquote>#5<br>#Create database 18c</blockquote><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/git_scripts/rundbca.sh’</blockquote><blockquote>#6<br>#listener</blockquote><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/oracle/scripts/start_lsnrctl.sh’</blockquote><blockquote>echo Database 18c is Ready to use !!</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dr_JpAwAuI8fgE1R8j_0wQ.png" /></figure><p>2. Automate_Create_DB : สำหรับการติดตั้งครั้งที่ 2 ขึ้นไป โดยคำสั่งภายในจะเป็นการเรียก script เพื่อสร้าง oracle database โดยจะมีการนับจำนวนครั้งในการสร้างเพื่อนำจำนวนดังกล่าวไปสร้างเป็นชื่อ database เพื่อไม่ให้ชื่อซ้ำกัน โดย database จะมีชื่อว่า jelly<em>[n] ** n แทนตัวเลขจำนวนครั้งที่ counter นับไว้</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FsHj3g2MO7mEtsH0wTKCwQ.png" /><figcaption>Project : Automate_Create_DB</figcaption></figure><p>โดยเราจะตั้งค่าลำดับการทำงานของ Jenkins ในการเรียก Scripts แต่ละตัวจากส่วนที่เป็น Build แบบ Execute Shell และใส่คำสั่งในการเรียก scripts ดังนี้</p><blockquote>#Create database 18c</blockquote><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/git_scripts/rundbca_generate.sh’</blockquote><blockquote>#listener</blockquote><blockquote>echo welcome1 | su oracle bash -c ‘sh /home/oracle/scripts/start_lsnrctl.sh’</blockquote><blockquote>echo Database 18c is Ready to use !!</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LuW5cHyrdcPQ2O2xoMaHOg.png" /></figure><p>NOTE1: Password Oracle คือ welcome1 , Password Root คือ P@ssw0rd<br>NOTE2: Password SYS , SYSTEM ของ database คือ welcome1 <br>สามารถแก้ไข password หลังจากสร้าง database แล้ว หรือสามารถแก้ไขใน script ก่อน execute Jenkins ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6w1suC_4HeG3MdDlV2z1fw.png" /><figcaption>Run Jenkins for Automation Install and Create Oracle Database 18c</figcaption></figure><p>เมื่อเราสร้าง Job ไว้ จะเห็น Job อยู่ที่หน้า Dashboard แบบนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pnYc27GZcfhJOfWDj1iXKA.png" /></figure><p>คลิกเข้าไปใน Job จะเจอปุ่ม Build Now ที่ซ้ายมือ ถ้าต้องการแก้ไขคำสั่ง Execute shell ก็สามารถเข้าไปที่เมนู configure</p><p>ตัวอย่างจาก project : Automate_Create_DB</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/927/1*otdqXMr7ZuQpeAGCsbCBzg.png" /></figure><p>เมื่อสั่ง Build Now แล้วจะเกิด status การทำงานอยู่ที่ช่อง Build History สามารถคลิกเข้าไปดู console ขณะกำลัง Build เพื่อ Monitor การทำงานหากมีความผิดพลาด status จะเป็นสีแดง หากสำเร็จ status จะเป็นสีฟ้า และ status จะเป็นสีเหลือง กรณีที่บางคำสั่งทำงานไม่สมบูรณ์</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/742/1*d6Znm_ti0u3yDnYszZUr2g.png" /></figure><p>ภายในหน้า console จะแสดงผลการทำงานเป็น log แบบนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*42nnGtYxkfZXsz7lWqmevg.png" /></figure><p>เมื่อเสร็จ ก็จะมีคำว่า “Database 18c is Ready to use !!” ตามที่เรากำหนดไว้ใน Execute shell</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kHvB4sJkITq1yVIuqPMrAw.png" /><figcaption>ทดสอบ status และ connection oracle จาก Linux host และ Windows host</figcaption></figure><p>เมื่อ คุณลุง Jenkins บอกว่าติดตั้งเสร็จแล้ว เราก็ไปลอง Connect Database กันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/869/1*msZw4d5j4GT34O9hUehshw.png" /><figcaption>ตรวจสอบ process pmon ของ Database</figcaption></figure><blockquote>$ ps -ef | grep pmon</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/629/1*sXzOYYKXTMktiai5lUfr2A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/1*tfc2Xt1e10UUZq8pDT5fBQ.png" /><figcaption>ตรวจสอบ status ของ listener database</figcaption></figure><blockquote>$ lsnrctl status</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/792/1*o74BPVaX3rnv1tV904JaPA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/874/1*5TSyY6YP-VFBkRv6ENwVoA.png" /><figcaption>Connect Database ภายในเครื่อง VM</figcaption></figure><blockquote>Export ORACLE_SID = jelly[n]</blockquote><blockquote>$ sqlplus / as sysdba</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/1*Z3DENDLle4Gy1Ngr4xQtpg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/883/1*jCqOBzpjMkH0qOccgUMI3g.png" /><figcaption>Easy connect จากเครื่อง Host (Windows 10)</figcaption></figure><blockquote>sqlplus sys/welcome1@172.20.10.3:1521/jelly[n] as sysdba</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*XIKTJwgB2rRT10ATBAtzyw.png" /></figure><p>เป็นยังไงกันบ้างคะ แค่สั่ง Build Now คลิกเดียว ก็มี Oracle Database พร้อมใช้งานอยู่ในเครื่องเลย</p><p>ประโยชน์และลูกเล่นของ Jenkins ยังมีอีกเยอะมากเลยนะคะ สามารถไปลองเล่นกันได้ สำหรับใครที่แวะเข้ามาชม Blog นี้และอยากจะแชร์ความรู้หรือแนะนำวิธีการใช้งาน Jenkins แบบ Advance แสดงความคิดเห็นมาได้เลยนะคะ</p><p>DBA ตัวน้อยๆ คนนี้ที่พึ่งหัดใช้ Jenkins เป็น ยินดีรับคำแนะนำเสมอค่ะ แล้วพบกันใหม่ Blog หน้านะคะ สวัสดีค่ะ :3</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YGuog4fvmDhl9fi_hd3b8w.png" /><figcaption><em>reference all cute icon from </em><a href="https://www.flaticon.com/packs/cute-food-2"><em>https://www.flaticon.com</em></a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6421e0c56cd2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sirisoft/%E0%B8%AA%E0%B8%A7%E0%B8%B1%E0%B8%AA%E0%B8%94%E0%B8%B5%E0%B8%84%E0%B9%88%E0%B8%B0%E0%B8%97%E0%B8%B8%E0%B8%81%E0%B8%84%E0%B8%99-%E0%B8%81%E0%B8%A5%E0%B8%B1%E0%B8%9A%E0%B8%A1%E0%B8%B2%E0%B8%9E%E0%B8%9A%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%AD%E0%B8%B5%E0%B8%81%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B8%99%E0%B8%B0%E0%B8%84%E0%B8%B0-%E0%B8%A2%E0%B8%B1%E0%B8%87%E0%B8%88%E0%B8%B3%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B9%84%E0%B8%94%E0%B9%89%E0%B8%AD%E0%B8%A2%E0%B8%B9%E0%B9%88%E0%B8%A1%E0%B8%B1%E0%B9%89%E0%B8%A2%E0%B8%99%E0%B9%89%E0%B8%B2-%E0%B8%AB%E0%B8%99%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B9%80%E0%B8%95%E0%B8%A2%E0%B8%A1%E0%B8%B2%E0%B9%80%E0%B8%82%E0%B8%B5%E0%B8%A2%E0%B8%99-blog-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%99%E0%B8%B5%E0%B9%89-6421e0c56cd2">ติดตั้ง Database แบบ Automation คลิกเดียวรู้เรื่อง!!</a> was originally published in <a href="https://medium.com/sirisoft">Sirisoft</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migrate Database to Docker Container ง่ายเวอร์ มาดูกันนน :D]]></title>
            <link>https://medium.com/sirisoft/migrate-database-to-docker-container-%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B9%80%E0%B8%A7%E0%B8%AD%E0%B8%A3%E0%B9%8C-%E0%B8%A1%E0%B8%B2%E0%B8%94%E0%B8%B9%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%99%E0%B8%99-d-2b23815b568a?source=rss-b8e4f73cd54f------2</link>
            <guid isPermaLink="false">https://medium.com/p/2b23815b568a</guid>
            <category><![CDATA[oracle-database]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[migration]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Orange’ Baitoey]]></dc:creator>
            <pubDate>Tue, 26 Dec 2017 05:30:29 GMT</pubDate>
            <atom:updated>2018-02-08T11:43:07.188Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PvIZtOF7MsZ7Sz7B-ldW-w.jpeg" /></figure><p>안녕하세요? อันนยองฮาเซโย ทุกท่านที่หลงเข้ามาใน blog นี้นะคะ วันนี้หน่องเตยมีเรื่องการ Migrate Database to Docker Container มาแชร์ค่ะ</p><p>โดยเนื้อหาจะเป็นการประยุกต์ใช้ Oracle Database version 12c กับเทคโนโลยีใหม่ที่ชื่อว่า Docker นั่นเอง โดยการ Migrate Oracle Database ของเราแบบ physical เข้าไป apply ใน docker container เพื่อให้เรามี data เช่น tables, users, privileges ต่างๆ ครบเหมือนยกข้อมูลจาก Production มาไว้สำหรับทดสอบ applications บน docker ด้วยขั้นตอนง่ายๆ เพียง 6 ขั้นตอนเท่านั้นค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bFZgg2OAgqMV-ieYdbheHQ.jpeg" /><figcaption>6 Steps for Migrate Database to Docker Container</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*XteK5IyVoEf4b9YSdGLnzw.jpeg" /><figcaption>Step 1 Install Docker software</figcaption></figure><p>Step 1 Install Docker software</p><p>สามารถเข้าไปศึกษา concept การทำงานของ Docker และวิธีการติดตั้ง Docker พร้อมแถมวิธีการสร้าง container ที่มี SQL server ได้ที่ <a href="https://medium.com/sirisoft/%E0%B8%A1%E0%B8%B2%E0%B8%A3%E0%B8%B9%E0%B9%89%E0%B8%88%E0%B8%B1%E0%B8%81%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%87%E0%B8%B2%E0%B8%99-docker-%E0%B8%9A%E0%B8%99-redhat-%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B9%80%E0%B8%96%E0%B8%AD%E0%B8%B0-44cf43188e62">Blog: มารู้จักการใช้งาน Docker บน RedHat กันเถอะ :)</a>เป็น Blog คุณภาพของเพื่อนหน่องเตยค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*cprdMuKioBgn1P72KQPvrg.jpeg" /><figcaption>Step 2 Create Database Container</figcaption></figure><p>Step 2 Create Database Container</p><p>สามารถเข้าไปศึกษาการติดตั้ง Oracle Database 12c r2 บน docker ได้ที่ <a href="https://medium.com/sirisoft/install-oracle-database-on-docker-container-1d1922b7d5cd">Blog:Install Oracle Database on Docker Container</a> Blog ดีๆ จากพี่ชายใจดีย์ของหน่องเตยเองค่ะ</p><p>หลังจากที่ทุกคนรู้จักเจ้า Docker พร้อมทั้งติดตั้งและสร้าง Oracle Database container กันเรียบร้อยแล้ว สามารถตรวจสอบและเข้า container ด้วยคำสั่ง ดังนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/1*Pcys4-gZyUiihkN-2gYBNQ.png" /><figcaption>คำสั่งดู container ทั้งหมด : docker ps -a</figcaption></figure><p>คำสั่ง start container : docker start &lt;container_name&gt;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/286/1*OwEaW08iZVHVIbrEoiTtIQ.png" /><figcaption>คำสั่ง start container : docker start &lt;container_name&gt;</figcaption></figure><p>คำสั่งดู container ที่กำลัง start อยู่ : docker ps</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*i0skjAiYhVmjMWmeyyx80A.png" /><figcaption>คำสั่งดู container ที่กำลัง start อยู่ : docker ps</figcaption></figure><p>คำสั่งเข้า container default user(oracle) : docker exec -it &lt;container_name&gt; bash</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/343/1*Zp9nghlcz86lKTM6EYL5SA.png" /><figcaption>คำสั่งเข้า container default user(oracle) : docker exec -it &lt;container_name&gt; bash</figcaption></figure><p>คำสั่งเข้า container root user : docker exec -it -u 0 &lt;container_name&gt; bash</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*kpiJTnA_V1_eLxo1l_BJ1Q.png" /><figcaption>คำสั่งเข้า container root user : docker exec -it -u 0 &lt;container_name&gt; bash</figcaption></figure><p>เมื่อเข้ามาใน container ได้แล้ว ทดลองใช้คำสั่ง sqlplus เพื่อเข้าสู่ SQL* Plus และสามารถใช้คำสั่ง sql ต่างๆ เพื่อจัดการและเรียกดูข้อมูลได้ ตัวอย่างตามรูปค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*e9QXMDXlCdorhZJC8lQKhw.png" /></figure><p>คราวนี้เรามาลองสร้าง database ของเราเองนะคะ แต่เนื่องจาก docker container นี้ไม่มีโหมด GUI เราเลยต้องติดตั้ง database silent mode แทนค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*1WQpa6QWRTVjCrEscgCcEQ.jpeg" /><figcaption>Step 2.1 Create New Database in Container</figcaption></figure><p>Step 2.1 Create New Database in Container</p><p>(แนะนำว่าให้ตั้งชื่อ ORACLE_SID ให้เหมือนกับ database ที่เราจะย้าย Datafiles มานะคะ จะได้ไม่สับสน)</p><p>คำสั่งเข้า create database silent mode : dbca -silent -createDatabase -templateName General_Purpose.dbc -gdbName ora12cdb -sid ora12cdb -responseFile NO_VALUE -SysPassword welcome1 -SystemPassword welcome1 -emConfiguration NONE -characterSet AL32UTF8 -memoryPercentage 20</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/423/1*DZlo6ZZ-cVz-SyD0ET__dw.png" /><figcaption>คำสั่งเข้า create database silent mode</figcaption></figure><p>** ขั้นตอนนี้อาจะใช้เวลาสักพัก ขอให้ทุกคนรออย่างใจเย็นนะคะ แอบไปซื้อขนมระหว่างรอก็ได้ค่ะ กลับมาเสร็จพอดี**</p><p>เมื่อสร้าง database ตัวใหม่เสร็จแล้ว ลองตรวจสอบ process ด้วยคำสั่ง ps -ef|grep pmon จะเห็น process database ทั้งสองตัวทำงานอยู่ค่ะ ตามรูปเลยยยยย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*o1vnN3Q8YYl_1KBeAZ90Fw.png" /><figcaption>คำสั่ง ps -ef|grep pmon</figcaption></figure><p>เมื่อเราจะสลับไปใช้ database ตัวใหม่ต้องใช้คำสั่ง : export ORACLE_SID=ora12cdb ก่อนค่ะ จะสามารถใช้ sqlplus ในการ query ข้อมูลจาก database ตัวใหม่ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*4bv4H40oIVsntBMKZ3FStw.png" /><figcaption>คำสั่ง : export ORACLE_SID=ora12cdb</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*dckuvKd42PqW-7Ubx6ySQA.jpeg" /><figcaption>Step 3 Check Datafiles Path</figcaption></figure><p>Step 3 Check Datafiles Path</p><p>เราต้องตรวจสอบก่อนว่าเดิม datafiles สำคัญทั้งหมดของ Database ora12cdb เครื่อง Production (เครื่องต้นทาง) อยู่ที่ path ไหนบ้างค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*g8vsHtn1T3hkLb1XfVGluQ.jpeg" /><figcaption>Step 3.1 Check Datafiles Path on Production</figcaption></figure><p>Step 3.1 Check Datafiles Path on Production</p><p>คำสั่งดู path control file : show parameter control_files</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*QVFMK2mNMGAbVkSUiTeTKA.png" /><figcaption>คำสั่งดู path control file : show parameter control_files</figcaption></figure><p>คำสั่งดู path data file : select file_name, tablespace_name, bytes from dba_data_files;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*RAU5Lpm-6hc8fAILqzFpAA.png" /><figcaption>คำสั่งดู path data file : select file_name, tablespace_name, bytes from dba_data_files;</figcaption></figure><p>คำสั่งดู path redo file : select * from v$logfile;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*wem4Y87eZwmc75uNMjMu6Q.png" /><figcaption>คำสั่งดู path redo file : select * from v$logfile;</figcaption></figure><p>คำสั่งดู path temp file : select file_name, tablespace_name, bytes from dba_temp_files;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*hf9TPSZAS7Pclf2POxKH2g.png" /><figcaption>คำสั่งดู path temp file : select file_name, tablespace_name, bytes from dba_temp_files;</figcaption></figure><p>คำสั่งดู path spfile : show parameter spfile</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*OPR5m0uesNYk9KiGPiJU5A.png" /><figcaption>คำสั่งดู path spfile : show parameter spfile</figcaption></figure><p>คำสั่งสร้าง pfile : create pfile=’path/pfile.ora’ from spfile=’path/spfile.ora’;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/553/1*W0fa22a2DP9zxe_FS_V6uA.png" /><figcaption>คำสั่งสร้าง pfile : create pfile=’path/pfile.ora’ from spfile=’path/spfile.ora’;</figcaption></figure><p>จะสังเกตได้ว่า control file, data file, redo file, temp file อยู่ใน path เดียวกัน มีแค่ control file02 และ pfile ที่อยู่ path อื่นค่ะ หลังจากที่เรารู้ว่า path ของไฟล์ต่างๆ ในเครื่องต้นทางอยู่ที่ไหน ก็ให้ทุกคนนำคำสั่งทั้งหมดนี้ไป ใช้กับ Database ora12cdb ที่ Docker Machine (เครื่องปลายทาง) ใน container ด้วยเช่นกันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*B08VqsTiD-LnCcADt_Of7w.jpeg" /><figcaption>Step 3.2 Check Datafiles Path on Docker Machine</figcaption></figure><p>Step 3.2 Check Datafiles Path on Docker Machine</p><p>คำสั่งดู path control file : show parameter control_files</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*ffciYV1QqPWEvEm-iBQG_A.png" /><figcaption>คำสั่งดู path control file : show parameter control_files</figcaption></figure><p>คำสั่งดู path data file : select file_name, tablespace_name, bytes from dba_data_files;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*mb3kr4FS8POAvMRd2oKktA.png" /><figcaption>คำสั่งดู path data file : select file_name, tablespace_name, bytes from dba_data_files;</figcaption></figure><p>คำสั่งดู path redo file : select * from v$logfile;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*PxpNueEoXJzwqRYfhoyLbQ.png" /><figcaption>คำสั่งดู path redo file : select * from v$logfile;</figcaption></figure><p>คำสั่งดู path temp file : select file_name, tablespace_name, bytes from dba_temp_files;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*UzwtnbK19-vM8RHAV8X4ng.png" /><figcaption>คำสั่งดู path temp file : select file_name, tablespace_name, bytes from dba_temp_files;</figcaption></figure><p>คำสั่งดู path spfile : show parameter spfile</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*-riFW3XWvimwHA2AJnnojQ.png" /><figcaption>คำสั่งดู path spfile : show parameter spfile</figcaption></figure><p>จะสังเกตได้ว่าเครื่องปลายทาง มี control file02 อยู่ที่เดียวกับ data file, redo file, temp file มีแค่ pfile ที่แยก path ไปนะคะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*rlazBVAgWiYVelOwRTvnvg.jpeg" /><figcaption>Step 4 Copy Datafiles</figcaption></figure><p>Step 4 Copy Datafiles</p><p>เมื่อเรามี list ไฟล์สำคัญ และ path เรียบร้อยแล้ว เราจะทำการ copy files ทั้งหมดนี้จากเครื่องต้นทาง ไปยังเครื่องปลายทางกันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*L2NvC0KqnUH4uRcsLYzfCA.jpeg" /><figcaption>Step 4.1 Copy Datafiles from Production to Docker Machine</figcaption></figure><p>Step 4.1 Copy Datafiles from Production to Docker Machine</p><p>ก่อนอื่นถ้าเครื่องต้นทางมีการใช้งานอยู่ตลอดเวลาแนะนำว่าให้ shutdown database ก่อน copy files ค่ะ (ถ้าเป็น production อาจจะต้องมี downtime สักพักค่ะ)</p><p>คำสั่ง shutdown immediate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/223/1*5TrRkw05rtGzfWzgvHLF8Q.png" /><figcaption>คำสั่ง shutdown immediate</figcaption></figure><p>เพื่อไม่ให้ทุกคนสับสน เราจะย้าย files ทั้งหมดนี้ไปรวมกันที่ folder dbfile ที่เครื่องปลายทางก่อนค่ะ ให้ทุกคนลอง cd เข้าไปตาม path ที่เรา list ไว้นะคะแล้ว copy files</p><p>คำสั่ง : scp path_file_on_host1 username@ip-address_host2:path_on_host2</p><p>* ถ้าใครงง ให้ดู ของหน่องเตยเป็นตัวอย่างไปเด้อออ เครื่องต้นทาง = host1 เครื่องปลายทาง = host2 ส่วนวิธีการดู IP นั้นใช้คำสั่ง ifconfig -a ค่ะ (OS linux) จะได้ IPhost2 : 192.168.1.159</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/364/1*8l6oTCAy0NxJYmqpWZOhow.png" /><figcaption>คำสั่ง ifconfig -a</figcaption></figure><p>สำหรับตัวอย่างนี้ จะได้คำสั่ง copy ตามนี้ค่ะ</p><p>scp /u01/app/oracle/oradata/ora12cdb/* root@192.168.1.159:/home/caramel/dbfile/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/1*8ynT7jfHsX3Bkmk_I2QHUQ.png" /></figure><p>scp /u01/app/oracle/fast_recovery-area/ora12cdb/control02.ctl root@192.168.1.159:/home/caramel/dbfile/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/1*nFFO6ZVacALmy6jJBxbKdQ.png" /></figure><p>scp /u01/app/oracle/product/12.2.0.1/db_1/dbs/pfile12122017 root@192.168.1.159:/home/caramel/dbfile/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*wCVZc-44CNiVLuD1zwQg7Q.png" /></figure><p>หลังจากย้ายไฟล์ครบทั้งหมดแล้ว อย่าลืมกลับไป start database ต้นทางด้วยนะคะ คำสั่ง startup</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/307/1*tlgE6aGHiVz-3K7zXtOinA.png" /><figcaption>คำสั่ง startup</figcaption></figure><p>มาดูกันค่ะว่า files ที่เรา copy มาที่ปลายทางครบหรือไม่…. คำสั่ง : cd /path_on_host2 และ คำสั่ง : ls -lhrt ทา ดา ~ *0* มากันพร้อมหน้าเชียววว</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*XAkyaPe3jMxh2kAH_EF8Zg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*P33jgK1E6IY91lNysG5QNg.jpeg" /><figcaption>Step 4.2 Copy Datafiles from Docker Machine to Container</figcaption></figure><p>Step 4.2 Copy Datafiles from Docker Machine to Container</p><p>ขั้นตอนนี้ เราจะต้องย้าย files ทั้งหมดนี้เข้าไปใน docker container ก่อนค่ะ โดยใช้คำสั่ง : docker cp path_on_host2 container_name:path_in_container สำหรับตัวอย่างนี้จะได้ คำสั่งนี้ค่ะ docker cp /home/caramel/dbfile/ oracledb:/home/oracle</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/578/1*IA1A5gzGxGxl7ZWmD3c2WQ.png" /></figure><p>ลองเข้าไปดูใน container กันค่ะว่าไฟล์เข้าไปหรือยัง ลืมคำสั่งเข้า container กันยังคะ คำสั่ง : docker exec -it &lt;container_name&gt; bash</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/343/1*Zp9nghlcz86lKTM6EYL5SA.png" /><figcaption>คำสั่ง : docker exec -it &lt;container_name&gt; bash</figcaption></figure><p>และ ใช้คำสั่ง : cd path_in_container กับคำสั่ง : ls -lhrt เข้าไปเช็คไฟล์กันเล้ยยยยย (ลุ้นนนนน)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/406/1*Hs7Bb7M8I2-YQYSRtmnODg.png" /><figcaption>คำสั่ง : cd path_in_container กับคำสั่ง : ls -lhrt</figcaption></figure><p>ไฟล์มาครบแล้วค่ะ แต่ทุกคนเห็นเหมือนกันไหมคะว่า ทุกไฟล์มี owner และ group เป็นของ root หมดเลย แต่เราเป็น user oracle group oinstall จะไม่สามารถกระทำการใดๆ กับไฟล์เหล่านี้ได้เลย เพราะฉะนั้นเราต้องเรา container อีก session นึงเป็น user root ค่ะเพื่อ เปลี่ยน owner files เป็น oracle เข้า container เป็น root ด้วย</p><p>คำสั่ง : docker exec -it -u 0 &lt;container_name&gt; bash</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*kpiJTnA_V1_eLxo1l_BJ1Q.png" /><figcaption>คำสั่ง : docker exec -it -u 0 &lt;container_name&gt; bash</figcaption></figure><p>และใช้คำสั่ง : chown -R oracle:oinstall dbfile/ ลองคำสั่ง : ls -lhrt อีกครั้งจะเห็นว่า owner และ group เปลี่ยนไปแล้วค่ะ กลับไป session แรกกันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/459/1*FnQwpaj-gjw02ZSoX_iyqg.png" /><figcaption>คำสั่ง : chown -R oracle:oinstall dbfile/</figcaption></figure><p>ตอนนี้เราจะย้ายไฟล์ต่างไปตาม path ของ container ตาม list ที่เราเก็บไว้ตอนแรกค่ะ (อย่าลืม backup files เดิมของ database ตัวนี้ไว้ก่อนด้วยนะคะ) และต้อง shutdown database ora12cdb ก่อนย้ายไฟล์ด้วยนะ</p><p>คำสั่ง : shutdown immediate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/439/1*UJo4qrqtoVOWQ3fwaTPGjA.png" /><figcaption>คำสั่ง : shutdown immediate</figcaption></figure><p>ส่วนการย้ายไฟล์ก็ง่ายๆค่ะ ใช้คำสั่ง : mv path_in_container path_db_in_container สำหรับตัวอย่างนี้จะได้ คำสั่งนี้ค่ะ mv /home/oracle/dbfile/* /opt/oracle/oradata/ora12cdb/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/571/1*dJHsHZRPmhD2otm3BXtaVw.png" /><figcaption>คำสั่ง : mv path_in_container path_db_in_container</figcaption></figure><p>ทุกไฟล์จะย้ายไปอยู่ที่ /opt/oracle/oradata/ora12cdb/ และจะเห็นไฟล์จะมี pfile ที่ติดมาด้วยและต้องย้ายไปอยู่ที่ path /opt/oracle/product/12.2.0.1/dbhome_1/dbs/ เหมือน spfile เราจะใช้คำสั่ง mv /home/oracle/dbfile/pfile12122017.ora /opt/oracle/oradata/ora12cdb/dbs/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*xLy8T5-QgyEhqvoy103D1w.png" /><figcaption>คำสั่ง mv /home/oracle/dbfile/pfile12122017.ora /opt/oracle/oradata/ora12cdb/dbs/</figcaption></figure><p>ตามไปดูที่ /opt/oracle/oradata/ora12cdb/dbs/ ไฟล์มาแล้วค่ะ เมื่อไฟล์จากต้นทางไปแทนที่ไฟล์ของปลายทางเรียบร้อยครบทุกไฟล์แล้ว เมื่อเราจะเปิด database ด้วยไฟล์ใหม่เหล่านี้ หน่องเตยขออธิบายคร่าวๆให้เข้าใจตรงกันก่อนค่ะว่า การ startup database เริ่มจากไฟล์ไหนบ้างที่เราพึ่ง copy มา</p><p>โดย database มี 4 states คือ shutdown, no mount, mount, open</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*jglCrHvhcKZHV7TEvjrIKQ.jpeg" /><figcaption>4 States of Database</figcaption></figure><ol><li>State Shutdown จะหยุดการทำงานและไม่สามารถเรียกดูข้อมูลใน database ได้</li></ol><p>2. State Nomount จะอ่านจาก init file (pfile) หรือ spfile โดยใน pfile จะเป็นตัวชี้ไปที่ control file ทำให้ไปยัง State Mount ต่อไปได้</p><p>3. State Mount ที่จะอ่าน control file โดยใน control file จะชี้ไปยัง data file, redo file, temp file ที่เป็นข้อมูลข้อ Database นั้นๆ จึงไปยัง state open ได้</p><p>4. State Open สามารถ query ข้อมูลได้เนื่องจาก database สามารถอ่านไฟล์ได้ทั้งหมด ดังนั้นไป ตรวจสอบความถูกต้องของไฟล์ที่จะถูกอ่านในแต่ละ state กันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*RjXof8_xFsoPqH0cnFjnZA.jpeg" /><figcaption>Step 5 Startup Database Step by Step</figcaption></figure><p>Step 5 Startup Database Step by Step</p><p>โดย state NOMOUNT ต้องอ่านข้อมูลจาก spfile/init file (pfile) ใช้คำสั่ง cd ไปที่ path pfile แล้วใช้คำสั่ง cat pfile12122017.ora</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/537/1*obG4fKNo4Otzr_GKhMUoag.png" /><figcaption>คำสั่ง cat pfile12122017.ora</figcaption></figure><p>จะเห็นว่ามีข้อมูลหลายอย่างในนี้ที่ยังเป็น ข้อมูลอ้างอิงจาก database ต้นทางเช่น path ของ control file เราจะต้องทำการแก้ไข ให้ถูกต้องเพื่อ pfile จะได้ชี้ไปอ่าน control file ใน state ถัดไป แต่เนื่องจากไม่สามารถใช้คำสั่ง vi ในการแก้ไขไฟล์ได้จึงใช้ cat &lt;&lt; EOF &gt; แทน ให้ทุกคน copy ข้อมูลในไฟล์ที่ cat pfile12122017.ora แสดงผลไว้ มาแก้ไขข้างนอกอาจจะวางใน notepad แล้วแก้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*sTlXaRWxU0mj7mCbD2I4pw.png" /></figure><p>จากนั้นใช้คำสั่ง : cat &lt;&lt; EOF &gt; แล้ววางข้อมูลที่เราแก้ไขไปทั้งหมด ตามด้วย EOF</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*KIxwVhzOOBaQSJetGNFKnQ.png" /><figcaption>คำสั่ง : cat &lt;&lt; EOF &gt;</figcaption></figure><p>ลองใช้คำสั่ง cat pfile12122017.ora อีกครั้งจะเห็นว่าข้อมูลในไฟล์เปลี่ยนไปเรียบร้อยแล้ว คราวนี้เราก็สามารถเปิด database ที่ state nomount ได้แล้วค่ะ โดยเข้า sqlplus ใช้คำสั่ง : startup nomount</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/1*Em-Pe7zYDkmDiT0Nkt5Dbg.png" /><figcaption>คำสั่ง : startup nomount</figcaption></figure><p>และใช้คำสั่ง : select status from v$instance; เพื่อตรวจสอบ state ของ database ซึ่ง no mount คือ START แบบในรูปค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/248/1*Sx8BBrDmRB9KVLH6fBCrVQ.png" /><figcaption>คำสั่ง : select status from v$instance;</figcaption></figure><p>เมื่อเข้า state nomount ได้ เราจะไป state ถัดไปคือ mount ค่ะ โดยใช้คำสั่ง : alter database mount;</p><p>state MOUNT</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/274/1*7MYnryVokb1XrkKyn52lQg.png" /><figcaption>คำสั่ง : alter database mount;</figcaption></figure><p>เมื่อเข้า state mount ได้ แสดงว่า pfile ชี้มาที่ control file path ที่ถูกต้อง ซึ่งใน control file นี้เป็นของ database ต้นทาง ซึ่งภายในจะเก็บข้อมูล file ต่างๆ ตาม path ในเครื่องต้น ทางเราต้องทำการ rename เพื่อเปลี่ยน path ให้ control file ชี้ไปที่ datafile ตาม path ปัจจุบันใน container โดยใช้คำสั่ง : alter database rename file ‘ path_file_on_host1_filename’ to ‘ path_db_in_container ‘;</p><p>สำหรับตัวอย่างนี้ จะได้คำสั่งตามนี้ค่ะ</p><p>alter database rename file ‘/u01/app/oracle/fast_recovery_area/ora12cdb/control02.ctl’ to ‘/opt/oracle/oradata/ora12cdb/control02.ctl’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/users01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/users01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/undotbs01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/undotbs01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/system01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/system01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/sysaux01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/sysaux01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/ts_test01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/ts_test01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/ts_test02.dbf’ to ‘/opt/oracle/oradata/ora12cdb/ts_test02.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/temp01.dbf’ to ‘/opt/oracle/oradata/ora12cdb/temp01.dbf’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/redo03.log’ to ‘/opt/oracle/oradata/ora12cdb/redo03.log’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/redo02.log’ to ‘/opt/oracle/oradata/ora12cdb/redo02.log’;</p><p>alter database rename file ‘/u01/app/oracle/oradata/ora12cdb/redo01.log’ to ‘/opt/oracle/oradata/ora12cdb/redo01.log’;</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*QjTCoXdnAh0nf0UObTz2Ug.png" /></figure><p>เมื่อเปลี่ยน path file ใน control s ครบแล้ว จะไป state ถัดไปคือ open โดยจะใช้คำสั่ง : alter database open; แล้วลอง เช็ค state database กันค่ะ</p><p>state OPEN</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/233/1*11ju4TWROCavn_kgwF3n7w.png" /><figcaption>คำสั่ง : alter database open;</figcaption></figure><p>ทา ดา ~ เห็นแบบนี้ค่อยชื่นใจหน่อย ในที่สุดเราก็สามารถวาร์ป database มาไว้บน docker ได้สำเร็จ มาลอง select ข้อมูลจาก table ที่เราย้ายมากันค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/301/1*pc5uAyy-pzJ-y5WqftYIYw.png" /></figure><p>เย้~ ตอนนี้ทุกคนก็มี database บน docker container ที่สามารถใช้ข้อมูลจริงของเราในการทดสอบ applications ต่างๆ ผ่าน docker กันเรียบร้อยแล้วนะคะ แต่!! อย่าพึ่งรีบปิดหนีกันไปไหนนะคะ หน่องเตยมี ทริปการ connect database แบบ GG EZ มาฝากค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*cid3UMDd02LTVm0bxX7YvA.jpeg" /><figcaption>step 6 Test Database Connection</figcaption></figure><p>step 6 Test Database Connection</p><p>โดยการ connect เข้า database แบบง่ายๆ command เดียว ก็ select ข้อมูลได้เลยนั้นทำไม่ยากค่ะ ให้ทุกคน ใช้คำสั่ง : cd $ORACLE_HOME/network/admin/ และลอง คำสั่ง : ls -lhrt ดู จะเจอไฟล์ชื่อว่า tnsname.ora เมื่อเราใช้คำสั่ง : cat tnsames.ora จะเห็นว่าในไฟล์นี้มีแค่ข้อมูล connection ของ database ชื่อว่า oracledb</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/315/1*8TQV0PITONhN3KkxhVTgfg.png" /><figcaption>คำสั่ง : cat tnsames.ora</figcaption></figure><p>ให้ทุกคน copy ข้อมูลนี้ออกมา และเปลี่ยนชื่อ เป็นชื่อ database ของเรา สำหรับตัวอย่างนี้ จะเปลี่ยนจาก oracledb เป็น ora12cdb ค่ะ แล้วใช้คำสั่ง cat &lt;&lt; EOF &gt;&gt; tnsname.ora เพื่อเพิ่มชุดข้อมูลนี้ต่อท้ายจากข้อมูลของ oracledb เดิมในไฟล์ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/1*nt81gqGfBqlycZc6W0QYKg.png" /><figcaption>คำสั่ง cat &lt;&lt; EOF &gt;&gt; tnsname.ora</figcaption></figure><p>แล้วลองใช้คำสั่ง cat tnsname.ora เพื่อดูว่าข้อมูลเพิ่มเข้าไปในไฟล์หรือไม่</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/395/1*cChA0IapTM-pHvY-0gsmUA.png" /><figcaption>คำสั่ง cat tnsname.ora</figcaption></figure><p>หลังจากนี้ให้ทุกคน exit ออกมาจาก container มาอยู่ใน เครื่อง host ด้วย user root นะคะ แล้วใช้คำสั่ง : cat /etc/hosts เพื่อดูว่ามีการกำหนด ชื่อ host และ เลข IP ของเครื่อง host ไว้หรือไม่ จากในรูปยังไม่มี IP ของเครื่องเราค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*-aI5hm3JgklyS9uuIqeygw.png" /><figcaption>คำสั่ง : cat /etc/hosts</figcaption></figure><p>เราจะใช้คำสั่ง : vi /etc/hosts เพื่อ insert 192.168.1.159 Caremel เพิ่มไป จะได้ตามนี้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/236/1*GCEDyjlor5KCCCG81TiDnA.png" /><figcaption>คำสั่ง : vi /etc/hosts</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/553/1*sWY0d3Mng_eG1HIa5pUkmg.png" /></figure><p>แล้วบันทึกไฟล์ ด้วยการพิมพ์ :wq</p><p>ตอนนี้เราก็มาเริ่ม connect database แบบ Easy สุดๆ กันด้วยคำสั่งเหล่านี้เลยค่ะ</p><p>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@ora12cdb ด้วยชื่อ database</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/409/1*gYdKEaxYjKMX_uv_2AxOtw.png" /><figcaption>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@ora12cdb ด้วยชื่อ database</figcaption></figure><p>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@0.0.0.0:1521/ora12cdb ด้วย localhost:port</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/461/1*Lcx7mOmuENwzLw_VzQsKfQ.png" /><figcaption>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@0.0.0.0:1521/ora12cdb</figcaption></figure><p>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@0.0.0.0:1521/ora12cdb ด้วย container IP:port</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*kTw5Bsd16xyuHuMkktTu5w.png" /><figcaption>คำสั่ง : docker exec -it oracledb sqlplus system/welcome1@0.0.0.0:1521/ora12cdb</figcaption></figure><p>คำสั่ง : sqlplus system/welcome1@192.168.1.159:1521/ora12cdb ด้วย command prompt จากเครื่องอื่น ผ่าน IP host ที่ติดตั้ง docker database ไว้ค่ะ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*mZ_KLkKL1uoO4t6UrhH0MA.png" /><figcaption>คำสั่ง : sqlplus system/welcome1@192.168.1.159:1521/ora12cdb</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/399/1*WeLvL_7LFVbNLv_eOZvbRg.png" /></figure><p>เป็นยังไงกันบ้างคะทุกคน หน่องเตยหวังว่า Blog นี้จะให้ความรู้กับทุกคนที่แวะมาเยี่ยมชมกันไม่มากก็น้อยเนอะ ส่วนใครมีคำแนะนำ ข้อเสนอแนะอะไร สามารถ comment ไว้ได้นะคะ ยินดีน้อมรับทุกคำติชมมาปรับปรุงค่ะ แล้วพบกันใหม่ Blog หน้า จะเป็นเรื่องเกี่ยวกับอะไรนั้น มาลุ้นกันเด้อออ</p><p>ช่วงขายของส่งท้าย ใครที่สนใจอยากรู้เรื่องการจัดการ docker cluster ด้วย kubernetes สามารถเข้าไปศึกษาต่อได้ที่ <a href="https://medium.com/sirisoft/getting-start-with-kubernetes-5b4e6b89241e">Blog: Getting Start … with Kubernetes </a>! Blog คุณภาพของ เจ้เบน ชุมชนบางซื่อส่งเข้าประกวดได้เลยค่ะ (แซว)</p><p>또 만납시다. โต มันนับชีดา แล้วพบกันใหม่นะคะ ฝากไลค์ ฝากแชร์ กันด้วยเด้ออออออออ จุ้บบบ :3</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2b23815b568a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/sirisoft/migrate-database-to-docker-container-%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B9%80%E0%B8%A7%E0%B8%AD%E0%B8%A3%E0%B9%8C-%E0%B8%A1%E0%B8%B2%E0%B8%94%E0%B8%B9%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B8%99%E0%B8%99-d-2b23815b568a">Migrate Database to Docker Container ง่ายเวอร์ มาดูกันนน :D</a> was originally published in <a href="https://medium.com/sirisoft">Sirisoft</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>