자주 쓰는 리눅스 명령어

 

리눅스에서 개인적으로 자주쓰는 명령어들

 

 

1. 폴더 및 파일 압축하기 & 압축풀기  

 

 - tar.gz으로 압축하기 (상대경로) 

    tar zcvf test.tar.gz test

 

    tar.gz으로 압축하기 (절대경로) 

    tar zcvfP /home/test.tar.gz /home/test

 

 

 - tar.gz 압축풀기

    tar zxvf test.tar.gz

 

  - gzip 으로 압축하기 

    gzip test

 

  - gzip 압축풀기 

    gunzip test.gz 

 

 

2. 리눅스에서 탭 사용하기 

 

   - command line에서 탭 사용하기 

       : ctrl + v 누르고 tab 누르기  

 

   - grep에서 탭 사용하기 

       : 탭은 \t로 표시하고 -P 옵션 사용 

        -P 옵션은 Perl regular expression을 사용 표시 

예시)  today_sorted=`date '-d yesterday' '+%d\t%m\t%Y'` 

       today_cnt_sorted=`grep -P -c $today_sorted $company".sorted"`

 
   - sed : \t로 사용 
           sed -i 's/ \t/\t/g' file

           sed -i 's/\t /\t/g' file

 

 

 

3. crontab 재시작하기

 

# /etc/init.d/crond restart

crond 를 정지 중:                                          [  OK  ]

crond (을)를 시작 중:                                      [  OK  ]

 

 
 

4. 리눅스 OS 확인 

$ cat /etc/issue

CentOS release 5.8 (Final)

Kernel \r on an \m

 
 
 
5. sed로 파일내에서 문자열 변환 
sed -i 's/short_news/feature_files/g'  filename
 
sed로 줄바꿈 제거
sed ':a;N;$!ba;s/\n/ /g' filenam
 
sed로 빈라인 제거
sed '/^$/d' 파일명 > 새 파일명
 
 
 
6. vi에서 붙여쓰기 계단현상 방지 
붙여쓰기 전에 :set paste 로 autoindent 등의 자동 들여쓰기 기능 정지시킴
그 후 :set nopaste로 다시 자동 들여쓰기 기능 활성화
또는 :set paste!로 기존 세팅 값 토글 

 

7. iptables 파일 보기 및 iptables 서비스 재시작하기 

 

vi /etc/sysconfig/iptables

 

service iptables restart

 

8. 현재 사용중인 shell 확인

# echo $SHELL

 

/bin/bash

 

 

 

9. ls로 디렉토리 목록만 보기

 

ls -d */

 

10. 폴더 안의 파일/폴더 사이즈 보기 

 

du -sh ./*

 

11. sudo로 ulimit 사용하기

sudo sh -c "ulimit -n 65535 && exec su $LOGNAME"

 

 

12. top 

 

- 명령어 메모리 사용 순으로 정렬하기

top -o %MEM

 

- MB, GB로 보기 

top화면에서 E를 입력하면 display 기준 사이즈가 변경됨 

 

13. 특정 조건의 파일들 찾기

- 크기가 1M 이상인 파일들 리스트 확인하기

find ./images/ -type f -size +1M | wc -l

find ./images/ -type f -size +1M | wc -l

리눅스에서 이미지 사이즈 줄이기

 

리눅스(ubuntu)에서 앱에 사용되는 이미지 폴더 사이즈가 너무 커지면서 

imagemagick 툴을 사용해서 이미지 사이즈를 줄여보기로 했다. 

 

설치

sudo apt install imagemagick 

 

실행

convert 명령을 사용해서 크기를 조정할 수 있다. 

 

convert --resize 옵션을 이용하여  파일의 크기를 원래 크기의 20%로 변경하였다. 

convert -resize 20% c6604cc4_small.png

사진 포맷 변경도 가능하다. png 파일을 jpg 파일로 변경하기만 해도 파일의 사이즈가 확 줄어든다.  

 

mogrify -format jpg \*.PNG  

파일 사이즈가 11M->411K, 600K->29K로 줄어든 것을 확인할 수 있다. 

-rw-rw-r-- 1 bi 411K Feb 19 21:02 5_large.jpg
-rw-r--r-- 1 bi  11M Feb 19 20:31 5_large.png
-rw-rw-r-- 1 bi  29K Feb 19 21:02 5_small.jpg
-rw-rw-r-- 1 bi 600K Feb 19 20:32 5_small.png

 

 

참고 : genuine-lamps.com/ko/linux/4502-how-to-resize-image-files-on-linux.html

blog.lael.be/post/370

인증서 갱신하기

 

운영중인 웹 사이트의 ssl 인증서가 만료되어서 갱신 하면서 절차를 기록하고 있음. 

 

도메인 갱신 절차 


1)  인증서 신청서 작성 접수 및 결제 완료
2)  신청서 접수 완료 메일 수신
3)  인증서 처리 예정 안내 SMS (또는 메일) 수신
4)  신청서에서 선택한 인증 수신 이메일에, Sectigo(해외)에서 DCV(영문) 메일 전송
5)  DCV 메일 수신 후, 인증 확인 설정. 완료. 끝.

6)  발급된 인증서를 서버에 적용 

7 ) SSL 적용 상태 및 인증서 정보 확인

 

www.comodossl.co.kr/certificate/ssl-renewal.aspx

 

SSL 인증서 갱신 안내 - HanbiroSSL

SSL 보안 서버 인증 가장 합리적인 가격의 Sectigo SSL 인증을 통해 귀사의 웹서버에 접속하는 회원들의 개인 정보를 안전하게 보호해 주시기 바랍니다. -->

www.comodossl.co.kr

 

www.comodossl.co.kr/apply/ssl-certificate-step1.aspx?brand=comodo&product=79&year=1

 

SSL 인증서 : 인증서 선택 및 정보 입력 - HanbiroSSL

SSL 보안 서버 인증 가장 합리적인 가격의 Sectigo SSL 인증을 통해 귀사의 웹서버에 접속하는 회원들의 개인 정보를 안전하게 보호해 주시기 바랍니다. -->

www.comodossl.co.kr

 

1) 인증서 신청서 작성 접수 및 결제 완료 

 

 

 

 

 

 

갱신이라 그런지 1년밖에 결재가 안된다. 매년 갱신하기 귀찮은데 다음에는 그냥 신규나 재발급으로 3년이나 5년 신청해두는 것이 좋을 것 같다. 

 

 

2-4) 도메인 소유자의 이메일에서 받은 validation code를 이메일에 보낸 링크에 입력하면 도메인 인증 절차 완료. 

 

You have entered the correct Domain Control Validation code. Your certificate will now be issued and emailed to you shortly. Please close this window now.

 

5) 사이트에 로그인해서 갱신된 ssl다운로드. 

 

6) 발급된 인증서를 서버에 적용

 

apache2 설정 파일 : /etc/apache2/

apache2 ssl 설정 파일 : /etc/apache2/sites-available/default-ssl.conf

 

인증서 파일 압축 풀면 나오는 

domain.key, domain.pfx, domain.crt 파일을 기존 ssl 파일 저장 폴더에 붙여넣기하고 

( 그전에 현재 ssl 폴더 및 설정 파일 백업 필수!)

아래와 같이 아파치 재시작을 하면 된다. 

 

service apache2 restart

 

7) 사이트에서 인증서 정보를 보니 인증서 갱신 성공!

 

 

MLP에서 적절한 hidden unit 개수 산정하기



sklearn MLP 알고리즘에서 적절한 hidden unit 개수 산정하기




skearn에서 MLP classifier나 regressor를 사용할때 

hiddenunit 개수를 몇 개로 시작해야 해야하는지에 대해서 좋은 대답이 있어서 기록해둔다.




  model_mlp = MLPClassifier(solver='lbfgs', alpha=1e-5, hidden_layer_sizes=(hiddenunit, 5), random_state=1)



If the NN is a regressor, then the output layer has a single node.


If the NN is a classifier, then it also has a single node unless softmax is used in which case the output layer has one node per class label in your model.


--


The number of hidden neurons should be between the size of the input layer and the size of the output layer.

The number of hidden neurons should be 2/3 the size of the input layer, plus the size of the output layer.

The number of hidden neurons should be less than twice the size of the input layer.






참고 : 

https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw


https://frhyme.github.io/python-lib/is_mlp_regressor_good/

php 시간 표현 예시 - dateTime 사용 예시



- 현재 시간 구하기 (YYYY-mm-dd) format




        $current_date = new DateTime();

        $current_date->format('Y-m-d');

  



- 현재 요일 구하기




function get_day_of_week($sql_date)

{

        $updated_date = new DateTime($sql_dat);

        $day_of_week = $updated_date->format('D');

        return $day_of_week;

}







- 두 시간 표현 간 시간 차이 구하기 

참고: http://haruair.com/blog/1871, http://php.net/manual/kr/datetime.diff.php





public DateInterval DateTime::diff ( DateTimeInterface $datetime2 [, bool $absolute = false ] )





       $date_db= new DateTime();

        $date_news=new DateTime("2014-01-28");

        $diff=$date_db->diff($date_news);

        print "\ndiff days".$diff->days; // 522



        if($date_news <= $date_db)

        {

            echo "\nnews data is older than or same as db\n";

            break;

        }

        else

        {

            echo "\nnews data is newer than db\n";


- 두 개의 시간 비교하기 

최신일 수록 값이 크기 때문에 오늘과 미래를 비교하면 비교식에서 미래가  오늘보다 더 크다 
 

<?php
$date1 = new DateTime("now"); or $date1= new DateTime();

$date2 = new DateTime("tomorrow");

var_dump($date1 == $date2);
var_dump($date1 < $date2);
var_dump($date1 > $date2);
?>

위 예제의 출력:

bool(false)
bool(true)
bool(false)





- 특정 날짜의 하루 전 날 구하기 

참고: http://php.net/manual/en/datetime.modify.php



<?php
$date = new DateTime('2006-12-12');
$date->modify('-1 day');
echo $date->format('Y-m-d');
?>








  • dd 2018.01.09 21:30 ADDR 수정/삭제 답글


    $date->modify('+1 month');

lightsail wordpress [pool wordpress] server reached pm.max_children setting (25) warninng




트래픽은 큰 차이가 안나는데 갑자기 cpu 사용량이 치솟으면서 사이트가 먹통이 되는 현상이 발생하였다. 

그 당시는 외부에서 발표중이여서 서버 재부팅으로 그 순간을 넘겼는데 그 후 같은 현상이 반복되서 원인 파악에 들어갔다. 


php-fpm 에러로그 파일 위치

/opt/bitnami/php/var/log/php-fpm.log


php-fpm 세팅 파일 위치

/opt/bitnami/php/etc/php-fpm.conf




bitnami@ip:/opt/bitnami/php/etc$ sudo cat /opt/bitnami/php/var/log/php-fpm.log

[15-May-2020 12:52:48] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 3 idle, and 13 total children

[15-May-2020 12:52:56] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 14 total children

[15-May-2020 12:53:00] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 18 total children

[15-May-2020 12:53:03] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 22 total children

[15-May-2020 12:53:07] WARNING: [pool wordpress] server reached pm.max_children setting (25), consider raising it

[15-May-2020 12:56:03] WARNING: [pool wordpress] server reached pm.max_children setting (25), consider raising it

[16-May-2020 06:16:58] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 3 idle, and 13 total children

[16-May-2020 06:17:07] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 3 idle, and 14 total children

[16-May-2020 06:17:08] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 3 idle, and 15 total children

[16-May-2020 07:52:26] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 2 idle, and 21 total children

[16-May-2020 07:52:29] WARNING: [pool wordpress] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 2 idle, and 23 total children

[16-May-2020 07:52:34] WARNING: [pool wordpress] server reached pm.max_children setting (25), consider raising it



워드프레스 pool쪽에서 문제가 생긴듯하다. 



참고로 php-fpm에서 사용하는 설정 파일(conf) 찾는법 


bitnam$ ps aux | grep php-fpm

root      3476  0.0  0.2 146396  9340 ?        Ss   08:20   0:01 php-fpm: master process (/opt/bitnami/php/etc/php-fpm.conf)

daemon    3477  0.6  0.6 153868 25196 ?        S    08:20   4:15 php-fpm: pool wordpress

daemon    3478  0.6  0.6 154064 25380 ?        S    08:20   4:09 php-fpm: pool wordpress



해당 설정파일을 가면 마지막에 두 개의 pool 설정 파일을 include 하고 있다. 




bitnam$ tail /opt/bitnami/php/etc/php-fpm.conf


include=/opt/bitnami/apps/wordpress/conf/php-fpm/pool.conf


include=/opt/bitnami/apps/phpmyadmin/conf/php-fpm/pool.conf


워드프레스 쪽의 설정 파일을 확인해본다. 


bitnami@ip$ cat /opt/bitnami/apps/wordpress/conf/php-fpm/pool.conf

[wordpress]

listen=/opt/bitnami/php/var/run/wordpress.sock

include=/opt/bitnami/php/etc/common-dynamic.conf

include=/opt/bitnami/apps/wordpress/conf/php-fpm/php-settings.conf

include=/opt/bitnami/php/etc/environment.conf

pm=dynamic




여기서 다시 common-dynamic.conf를 include하고 있다. 

다시 그 파일 설정으로 들어가면 common.conf 파일을 include하고 있다. 

common.conf 파일까지 가야지 드디어 


bitnami$ cat /opt/bitnami/php/etc/common-dynamic.conf

include=/opt/bitnami/php/etc/common.conf

pm=dynamic

pm.max_children=5

pm.start_servers=2

pm.min_spare_servers=1

pm.max_spare_servers=3


include=/opt/bitnami/php/etc/bitnami/common.conf




bitnami$ cat /opt/bitnami/php/etc/bitnami/common.conf

;

; Bitnami PHP-FPM Configuration

; Copyright 2019 Bitnami.com All Rights Reserved

;

; Note: This file will be modified on server size changes

;

pm.max_children=25

pm.start_servers=4

pm.min_spare_servers=4

pm.max_spare_servers=10

pm.max_requests=5000



각각의 옵션 설명은 아래 설정 파일의 설명을 참고하면 된다. 


; Choose how the process manager will control the number of child processes.

; Possible Values:

;   static  - a fixed number (pm.max_children) of child processes;

;   dynamic - the number of child processes are set dynamically based on the

;             following directives. With this process management, there will be

;             always at least 1 children.

;             pm.max_children      - the maximum number of children that can

;                                    be alive at the same time.

;             pm.start_servers     - the number of children created on startup.

;             pm.min_spare_servers - the minimum number of children in 'idle'

;                                    state (waiting to process). If the number

;                                    of 'idle' processes is less than this

;                                    number then some children will be created.

;             pm.max_spare_servers - the maximum number of children in 'idle'

;                                    state (waiting to process). If the number

;                                    of 'idle' processes is greater than this

;                                    number then some children will be killed.

;  ondemand - no children are created at startup. Children will be forked when

;             new requests will connect. The following parameter are used:

;             pm.max_children           - the maximum number of children that

;                                         can be alive at the same time.

;             pm.process_idle_timeout   - The number of seconds after which

;                                         an idle process will be killed.

; Note: This value is mandatory.





pm.max_children 수를 50으로 증가시키고 php-fpm을 재시작해서 변경 사항을 반영한다. 


sudo /opt/bitnami/ctlscript.sh restart php-fpm







그런데 이 포스팅을 작성하면서 cpu 사용량이 조금씩 상승하고 있어서 아파치 접속 로그를 확인해봤더니 

아래와 같이 존재하지 않는 경로를 요청하는 수상한 ip들이 보여서 검색해보니 최근에 스팸 등으로 블랙리스트에 신고된 아이피였다. 


https://cleantalk.org/blacklists/173.212.194.14



bitnami$ tail -f /opt/bitnami/apache2/logs/access_log


173.212.194.14 - - [17/May/2020:00:22:28 +0900] "GET /product-tag/med/?product_orderby=popularity&product_count=24&product_view=grid&product_order=asc HTTP/1.1" 301 -

173.212.194.14 - - [17/May/2020:00:22:47 +0900] "GET /?product_orderby=popularity&product_count=24&product_view=grid&product_order=asc HTTP/1.1" 200 22179




이것만은 원인은 아니겠지만 그래도 원인 중 하나일 것 같아서 워드프레스 보안 플러그인 설정 변경도 해야겠다. 




php-fpm status 쉽게 확인하는 법




; By default the status page output is formatted as text/plain. Passing either

; 'html', 'xml' or 'json' in the query string will return the corresponding

; output syntax. Example:

;   http://www.foo.bar/status

;   http://www.foo.bar/status?json

;   http://www.foo.bar/status?html

;   http://www.foo.bar/status?xml

;

; By default the status page only outputs short status. Passing 'full' in the

; query string will also return status for each pool process.

; Example:

;   http://www.foo.bar/status?full

;   http://www.foo.bar/status?json&full

;   http://www.foo.bar/status?html&full

;   http://www.foo.bar/status?xml&full

; The Full status returns for each process:

;   pid                  - the PID of the process;

;   state                - the state of the process (Idle, Running, ...);

;   start time           - the date and time the process has started;

;   start since          - the number of seconds since the process has started;

;   requests             - the number of requests the process has served;

;   request duration     - the duration in µs of the requests;

;   request method       - the request method (GET, POST, ...);

;   request URI          - the request URI with the query string;

;   content length       - the content length of the request (only with POST);

;   user                 - the user (PHP_AUTH_USER) (or '-' if not set);

;   script               - the main script called (or '-' if not set);

;   last request cpu     - the %cpu the last request consumed

;                          it's always 0 if the process is not in Idle state

;                          because CPU calculation is done when the request

;                          processing has terminated;

;   last request memory  - the max amount of memory the last request consumed

;                          it's always 0 if the process is not in Idle state

;                          because memory calculation is done when the request

;                          processing has terminated;

; If the process is in Idle state, then informations are related to the

; last request the process has served. Otherwise informations are related to

; the current request being served.

; Example output:

;   ************************

;   pid:                  31330

;   state:                Running

;   start time:           01/Jul/2011:17:53:49 +0200

;   start since:          63087

;   requests:             12808

;   request duration:     1250261

;   request method:       GET

;   request URI:          /test_mem.php?N=10000

;   content length:       0

;   user:                 -

;   script:               /home/fat/web/docs/php/test_mem.php

;   last request cpu:     0.00

;   last request memory:  0

;

; Note: There is a real-time FPM status monitoring sample web page available

;       It's available in: /bitnami/lamp73stack-linux-x64/output/php/share/php/fpm/status.html

;

; Note: The value must start with a leading slash (/). The value can be

;       anything, but it may not be a good idea to use the .php extension or it

;       may conflict with a real PHP file.

; Default Value: not set

;pm.status_path = /status






그리고 응답이 늦어지는 상황을 좀 더 모니터링 하기 위해 slowlog를 설정한다


; The log file for slow requests

; Default Value: not set

; Note: slowlog is mandatory if request_slowlog_timeout is set

;slowlog = log/$pool.log.slow


; The timeout for serving a single request after which a PHP backtrace will be

; dumped to the 'slowlog' file. A value of '0s' means 'off'.

; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)

; Default Value: 0

;request_slowlog_timeout = 0



최종 변경사항들은 아래와 같다. 


pm.status_path = /status

slowlog = log/$pool.log.slow

request_slowlog_timeout = 0




참고: https://www.tecmint.com/enable-monitor-php-fpm-status-in-nginx/


https://stackoverflow.com/questions/15465333/php-fpm-processes-monitoring-profiling


https://docs.bitnami.com/aws/apps/wordpress-pro/configuration/configure-phpfpm-processes/


https://www.php.net/manual/en/install.fpm.configuration.php

pandas : TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'Index'




pandas 에러 처리



  TypeError: Only valid with DatetimeIndex,

 TimedeltaIndex or PeriodIndex, but got an instance of 'Index'





기계학습 실험을 하기 위해 그냥 평상시처럼 csv 파일을 아래와 같이 읽어왔다. 





rawdata = pd.read_csv("/data/training.csv", parse_dates =["date"], index_col ="date", sep='\t', encoding='utf-8')


...


ds['vacancy'].resample(rule='M').mean().plot('bar')


필드별 통계를 보기위해 resample을 했는데 아래와 같은 에러가 발생하는 것이다?!


pandas :  TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'Index'


resample을 하기위해서는 datetimeindex가 있어야하는데 index만 있다는 것이다. 


csv 읽어올때 parse_dates 옵션을 줬는데도 info를 확인해보니 datetimeindex가 아닌 index로 걸려있었다. 






nan을 보니 빈문자열이 있는 것 같아서 삭제했는데도 index만 걸려있다. 


to_datetime 함수로 명확하게 필드 타입 변환을 해보기로 했다. 

에러를 확인해야하니 errors='raise'로 설정하였다. 




ds['date'] = pd.to_datetime(rawdata['date'].str.strip(), format='%Y-%m-%d', errors='raise')


아래 date라는 필드명과 에러가 나는 문자열 이름이 같아서 좀 헷갈렸는데 

date라는 문자열이 해당 date 필드에 들어있어서 문자열 변환에서 오류가 난 것이다. 

중간에 컬럼명이 한번 더 들어간 모양이다. 



ValueError: time data u'date' does match format specified



이렇게 해서 해결! 인 줄 알았는데 아래와 같이 이상한 문자열 에러는 계속 나왔다 ㅠㅠ

정부 open API로 데이터를 수집한 것은 좋은데 검증은 안하고 그냥 데이터 보내나 보다 ㅠㅠ


time data u'0973-04-12' does match format specified

ValueError: time data u'9187-06-08' does match format specified

ValueError: time data u'0999-09-08' does match format specified

time data u'1669-09-11' does match format specified



위 문자열까지 해결하니 제대로 datetimeindex 걸린것을 확인할 수 있었다. 


<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 102918 entries, 1960-12-17 to 2020-06-23
Data columns (total 36 columns):
opnSvcNm         102918 non-null object






postgres 데이터 파일로 저장하기


https://www.postgresql.org/docs/10/static/sql-copy.html




postgresql 테이블의 데이터를 csv로 저장하려면 copy to 문을 사용하면 된다. 

아래 copy 문법과 예시 참조할 것. 



문법 ) 

COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | STDIN }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE NOT NULL column_name [, ...] ] ] ]

COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }
    TO { 'filename' | STDOUT }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE QUOTE { column_name [, ...] | * } ] ] ]


delimiter는 구분자를 무엇으로 할 지 지정하는 옵션이다. 


force quote는 컬럼에서 null이 아닌 컬럼 내용을 둘러싸는 기능을 이야기 한다. 

컬럼 이름을 설정해서 그 컬럼만 할 수 있고 *를 선택하면 전체 컬럼에 반영이 된다. 

copy to 에서 csv format을 선택할때만 사용할 수 있는 옵션이다. 



If * is specified, non-NULL values will be quoted in all columns. This option is allowed only in COPY TO, and only when using CSV format.



예시 1 ) , 를 구분자로 해서 파일로 저장하는 케이스 





COPY (

    SELECT language, title FROM cms_title WHERE language != 'en' AND title != 'Blog'

) TO '/path/to/csv/cms_title_dump.csv' WITH CSV HEADER DELIMITER ';';







예시 2) 빈 문자열을 구분자로 하고 "로 칼럼을 감싸서 저장하는 케이스 




copy (  select name, name, bldnm from table1 ,table2 where table1.id = table2.id order by namecnt desc)

to '/home/housename.csv' with csv header DELIMITER ' ' FORCE QUOTE *;



output 

name,name,bldnm
"엘지메트로시티2","엘지메트로시티2","엘지메트로시티"
"파크리오","파크리오","파크리오"
"성원","성원","성원아파트"
"잠실엘스","잠실엘스","잠실엘스"



예시 3) 중간에 다른 문자를 포함해서 저장하는 케이스 



copy (  select name, '{', name, bldnm, '}'  from table1 ,table2 where table1.id = table2.id order by namecnt desc)

to '/home/housename.csv' with csv header DELIMITER ' ';





예시 4 ) 탭으로 구분자를 할 경우 





COPY (

    SELECT language, title FROM cms_title WHERE language != 'en' AND title != 'Blog'

) TO '/path/to/csv/cms_title_dump.csv' WITH CSV HEADER DELIMITER E'\t';






















postgresql 테이블에 칼럼 추가 + 커멘트 달기






postgresql 테이블에 칼럼 추가 + 커멘트 달기




칼럼 추가 방식 


ALTER TABLE 테이블명 ADD COLUMN 컬럼명 데이터타입 제약조건


참고) postgresql numeric type


 



예시 


- int 형의 칼럼 추가하고 코멘트 달기


ALTER TABLE 테이블이름 ADD 칼럼이름 integer;

COMMENT ON COLUMN 테이블이름.칼럼이름 IS '코멘트';


- numeric 형의 칼럼 추가하기


ALTER TABLE 테이블이름 ADD COLUMN "ERROR" numeric(5,3);


칼럼 이름을 대문자로 할 경우 ""로 감싸줍니다. 




- varchar 칼럼 추가하면서 default 값 설정하기  


ALTER TABLE test_tb ADD COLUMN name varchar(50) DEFAULT 'NONAME'


- character varying 사이즈 120인 칼럼 추가하기 


ALTER TABLE test_tb ADD COLUMN name character varying(120)



default 값이 있는 칼럼을 추가할 경우 

postgresql 10 이하 버전에서는 테이블을 다시 생성하기 때문에 

시간도 오래 걸리고 그 동안에 access exclusive lock 에 걸리게 됩니다. 

access exclusive lock 은 lock level 중 제일 높은 레벨로 select 까지 막히게 됩니다. 

(실서비스 하는 데이터베이스에서 매우 곤란한 상황 ; - ; ) 


그럴 경우 한번에 칼럼을 추가하고 default 값을 설정하는 것보다는

아래의 예시와 같이 칼럼을 추가하고 기본 값을 설정하는 것이 좋습니다. 



ALTER TABLE test_tb ADD COLUMN name varchar(50);

update test_tb set name = 'NONAME';


ALTER TABLE items ADD COLUMN updated_at timestamptz;

UPDATE items SET updated_at = now();


 


참고

https://americanopeople.tistory.com/272

https://americanopeople.tistory.com/292?category=695027

https://www.postgresql.org/docs/10/datatype-numeric.html









lightsail로 워드프레스 사이트 시작하기- 6) 디스크 증설하기


라이트세일로 워드프레스 사이트 시작하기


6) 디스크 증설하기



서비스를 운영하다보니 이미지 업로드가 많아지면서 어느샌가 디스크가 부족해졌다. 

얼추 보았을때는 aws lightsail console에서 아래에 있는 버튼 하나로 

디스크를 추가할 수 있는 걸로 보인다.  








실제로 디스크를 추가하면 instance에 부착까지는 

아래 과정을 통해 한번에 된다. 










그런데 df -h를 하면 새로 추가한 디스크가 나오지 않는다 

아래 링크를 확인하면 디스크 포맷부터 mount를 스스로 해야 한다고 친절하게 알려준다(...)


나 이거 봤어. 서버 세팅 혼자 하던 시절...


예전에 물리 서버 혼자 운영할때도 다 했는데 

aws도 마찬가지구나(...)



https://lightsail.aws.amazon.com/ls/docs/en_us/articles/create-and-attach-additional-block-storage-disks-linux-unix



작업내용 


새로 mount할 디스크를 기존 디스크와 같은 형태의 파일시스템으로 포맷합니다. 

이떄 꼭 새로 붙이는 디스크가 비어있는지 확인해야합니다. 

디스크 내용이 들어있으면 포맷하지 마세요!


$ df -h

Filesystem      Size  Used Avail Use% Mounted on

udev            2.0G     0  2.0G   0% /dev

tmpfs           396M   11M  385M   3% /run

/dev/xvda1       78G   43G   35G  56% /

tmpfs           2.0G     0  2.0G   0% /dev/shm

tmpfs           5.0M     0  5.0M   0% /run/lock

tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup

/dev/loop0       29M   29M     0 100% /snap/amazon-ssm-agent/2012

/dev/loop2       18M   18M     0 100% /snap/amazon-ssm-agent/1566

/dev/loop1       97M   97M     0 100% /snap/core/9436

/dev/loop3       97M   97M     0 100% /snap/core/9665

tmpfs           396M     0  396M   0% /run/user/1000


lsblk로 mount 정보 확인 

$ lsblk

NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT

xvda    202:0    0   80G  0 disk

└─xvda1 202:1    0   80G  0 part /

xvdf    202:80   0  256G  0 disk

loop0     7:0    0 28.1M  1 loop /snap/amazon-ssm-agent/2012

loop1     7:1    0 96.5M  1 loop /snap/core/9436

loop2     7:2    0   18M  1 loop /snap/amazon-ssm-agent/1566

loop3     7:3    0   97M  1 loop /snap/core/9665


새로 mount할 디스크 파일 타입 확인 

$ sudo file -s /dev/xvdf

/dev/xvdf: data


기존에 mount되어있는 디스크 파일 타입 확인합니다. ext4를 사용하고 있네요. 

$ sudo file -s /dev/xvda1

/dev/xvda1: Linux rev 1.0 ext4 filesystem data, UUID=9bd74952-5d49-4ac3-8b92-6491cf32a505, volume name "cloudimg-rootfs" (needs journal recovery) (extents) (large files) (huge files)



새로운 디스크도 ext4타입으로 포맷합니다. 이떄 꼭 새로 붙이는 디스크가 비어있는지 확인해야합니다. 

디스크 내용이 들어있으면 포맷하지 마세요!


$ sudo mkfs -t ext4 /dev/xvdf

mke2fs 1.42.13 (17-May-2015)

Creating filesystem with 67108864 4k blocks and 16777216 inodes

Filesystem UUID: 1fba4148-faac-4675-a772-87a67e1b9d6d

Superblock backups stored on blocks:

        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,

        4096000, 7962624, 11239424, 20480000, 23887872


Allocating group tables: done

Writing inode tables: done

Creating journal (32768 blocks): done

Writing superblocks and filesystem accounting information: done




새로 포맷한 디스크의 파일 타입을 확인하고 마운트를 실행한다. 




새로 포맷한 디스크의 파일 타입 확인. 

$ sudo file -s /dev/xvdf

/dev/xvdf: Linux rev 1.0 ext4 filesystem data, UUID=1fba4148-faac-4675-a772-87a67e1b9d6d (extents) (large files) (huge files)


마운트할 위치에 디렉토리를 생성하고 

$ sudo mkdir /data


sudo mount device_name mount_point 로 mount를 실행한다. 

$ sudo mount /dev/xvdf /data


df -h로 잘 마운트 되었는지 확인한다. 

$ df -h

Filesystem      Size  Used Avail Use% Mounted on

udev            2.0G     0  2.0G   0% /dev

tmpfs           396M   11M  385M   3% /run

/dev/xvda1       78G   48G   30G  62% /

tmpfs           2.0G     0  2.0G   0% /dev/shm

tmpfs           5.0M     0  5.0M   0% /run/lock

tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup

/dev/loop0       29M   29M     0 100% /snap/amazon-ssm-agent/2012

/dev/loop2       18M   18M     0 100% /snap/amazon-ssm-agent/1566

/dev/loop1       97M   97M     0 100% /snap/core/9436

/dev/loop3       97M   97M     0 100% /snap/core/9665

tmpfs           396M     0  396M   0% /run/user/1000

/dev/xvdf       252G   60M  239G   1% /data




새로운 디스크 포맷할때 왠지 걱정되서 기존 서버 백업도 해두고 그랬는데 

그냥 별문제없이 금방 끝났네요. 


이렇게 디스크 증설이 별 문제없이 마무리되었습니다.